requests模块使用二
1、cookies和session
1.1、什么是cookie和session?
cookie是网站用来辨别用户身份,进行会话跟踪,存储在本地终端上的数据。
session(会话)起来本含义是指有始有终的一系列动作和消息。
在web中,session主要用来在服务器端存储特定用户对象会话所需要的信息。
1.2、cookie和session产生的原因:
http协议是一个无状态协议,在特定操作的时候,需要保存信息,进而产生了cookie和session。
1.3、cookie原理:
由服务器来产生,浏览器第一次请求,服务器发送给客户端进而保存,浏览器继续访问时,就会在请求头的cookie字段上附带cookie信息,这样服务器就可以识别是谁在访问了。
但是cookie存在缺陷:
1、不安全--本地保存,容易被篡改。
2、大小受限,本身最大4kb。
cookie虽然在一定程度上解决了‘保持状态’的需求,但是我们希望有一种新的技术可以克服cookie缺陷,这种技术就是session。
1.4、session
session在服务器保存。----解决安全问题。
问题来了:服务器上的session,但是客户端请求发送过来,服务器如何知道session_a,session_b,到底和那个请求对应。
所以为了解决这个问题:cookie就作为这个桥梁。在cookie有一个sessionid字段,可以用来表示这个请求对应服务器中的哪一个session。
禁用cookie,一般情况下,session也无法使用。特殊情况下可以使用url重写技术来使用session。
url重写技术:将sessionid拼接到url里面。
session的生命周期:服务器创建开始,有效期结束(一般网站设定都是大约30分钟左右),就删除。
1.5、cookie常用字段
"domain": ".baidu.com", #主机名
"expirationDate": 1607430402.780818, #过期时间(时间戳=>等价于Tue Dec 8 20:26:42 2020)
"name": "BAIDUID", #字段名
"path": "/", #主机哪个路径下设置的cookie
"secure": false, 是否安全传输
"value": "FC48EB3E32989D00F7BFCA9AF76D009A:FG=1", #字段值
"id": 1 #cookiesid
1.6、会话cookie和持久cookie
会话cookies:
"expirationDate"的值为负数,则关闭浏览器时cookie 即失效,保存在内存中的cookie。
持久cookies
"expirationDate": 1607430402.780818 , 则该cookie 在时间为expirationDate的时候失效。 保存在硬盘上的cookie
持久化:将内存中数据持久化到硬盘上。其实就是数据保存到文件或者数据库中。
内存主要的作用就是由于速度快,启动应用软件或者程序的时候,就会分配一定内存空间作为该程序的执行空间。
内存一旦断电,就会被清空。
1.7、通过cookies 登录github页面
cookies 在requests中使用的第一种方式(将cookies放置在headers中)
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
'Cookie': '_octo=GH1.1.90071fdfg1199.1575898561; _device_id=78c6d6dc75b0d87dg7afb73742a9679aa9; _ga=GA1.2.1521343976.1575898582; has_recent_activity=1; tz=Asia%2FShanghai; experiment:homepage_signup_flow=eyJ2ZXJzaW9uIjoiMSIsInJvbGxPdXRQbGFjZW1lbnQiOjM1LjE2NzQ2NjU3Nzg3OTk1Niwic3ViZ3JvdXAiOm51gdfbGwsImNyZWF0ZWRBdCI6IjIwMjAtMDMtMThUMDI6MDQ6MjMuODA4WiIsInVwZGF0ZWRBdCI6IjIwMjAtMDMtMjVUMDQ6MTk6MTUuNjA5WiJ9; user_session=jk2HfEj_4gWfU8V_4dvps7naVFFB_R0aUn4_mVrdxnQWy9u7; __Host-user_session_same_site=jk2HfEj_4gWfU8V_4dvps7naVFFB_R0aUn4_mVrdxnQWy9u7; logged_in=yes; dotcom_user=2829507692; _gh_sess=x0LIdSUTKSwhKICq0QYKsXlDJULU%2BjhBdrK8NzsFYwNIUOHV0gYsMgjLZ%2B8YgTBoSp%2FjMZXHhuMfdD4dr7sqV%2F1IF%2BA0GnYV6J%2BsyyoMxpoz%2BVOdYGWqUi4p5KOIxm6VAOyePx6fEM21VAGMdEqq9EXErfH0n3j81aFFQeKYv3TgkEWqpYbD6DNKWrUOB%2FrbwmyND0z%2BdjrTLDE6YbZnwZwEoaiIZUhd6Rd265uMBD%2B38uNc7jHQRl1TVrfPwHTHXi%2BfE4LSzMOZalVQgoNlGxi0o0QXwa%2F12pt97CFIUjnSIqYwBEEVkl81pVBhjVzkKWQsKLPaSArMJ3wDPBKHegQCRLZ3u2lMa2%2BZTLKnOsA20%2BX9Z%2B2DdRPL9UHusnUME%2F77KC4V%2FNrHMKnPkLC2dpZFojKSZscTpjBB4PeYF4KV84sMOMrxQlHetWDKN8%2BcjSuHPOGdf2qHq67AbyaRsoyFK3T2cQocIqJh9pYEQwmnm%2FasWoP82PsAn%2FbujQY%2BzJq1iVWxVUCH0nc5mShuwJg0AJBjAiaFwSvCjWF5eUFYmKTA9Bk%2FpH254MbDb8ofJsWJs6m1oycxEuJogMHkxZuIrWGIQezG%2BBYODyTJOco4oGRp11dVTPZLXTj3Vet0pwvL749B8hfmskK%2F4w2mvErIoxxe6yy1u0kgwgq4xIcgwmsdfg0I7ZUQC6ak0cGNfOeomjoTSPNLT0DZoUFW4WSjhiGgxIiUowPFB9PQ9FCvxrw8%2FyV0foedzTKQVZUnru7Ik4XkYpKakmfzZRPn5soED4XFgJVmzTB4xVxQSHNzsDgwBWupZYxE5dcYitWVr3OrMYAeqzpc%2BVbEs8%2BtWNpKDlJDOMYQfsqwGexThnNYlj2IvnIz0aQydEva%2FNcZNlHOiEaD%2BN8xdMyqd2GTydT1LjkizWv4SofUNjroCj3mgggH2hCcOwRUhcYUJZt8Z6gW7JYiLCxQqnjVrJBc%2Bw2dgg1scohQhZ6PXkk5IqvX3p2mP2Xq967TEqr4bqntFcARsTUM4bT54D81XHiS6g1Rue0QmXu3pxe%2BEiMpoptbMRcQFsPQqE8PhweZKCL9ZOW0637rmt4qVNuQdvfGi9N2Bs9aO4PjDk%2Brrj5tWhSSzdCRUbYWzhtNj9CXImyQZoTZ7aPKrgRd2tjiEl5l61uPfdAvd%2FXv4dKxXbUlIb3TLhNsmJExDgdgfj7CoSiysaKwluM4D2Ggbk9xqtvSI9g57PweEA%2BhoxnjZKI0It65ZgZ5bIX7ipEEAo14uLPsqGut6ittBEp1UT5xELjUaM6LPto%2F9IPLlG4U8mdb3u7xx%2BuTakRu7yfbabDUkv0QXY9nsg3u27eTg097WErlgeB7jqf%2Flc%2Ft8laI%2B641xqA2kKKcr38PYwrkbySJyf5TMjgLop6qFCo738w%2B8J409OIEqNREN0IoW0DrfELoHmAkhMAYyzY2Yynbs3973wyyOTZUwNvm4K0mQQ%3D%3D--07oaTkbSmNfGWujT--xcmABMjlD5SJ9u8LnSFp%2Bwdsf%3D%3D'
}
url = 'https://github.com/'
res = requests.get(url, headers=headers).content.decode('utf-8')
if 'username' in res:
print('login True')
cookies 在requests中使用的第二种方式(将cookies放置在cookies参数中)
import requests
cookies='_octo=GH1.1.900711199.1575898561; _device_id=78c6d6dc75b0d877afb73742a9679aa9; _ga=GA1.2.1521343976.1575898582; has_recent_activity=1; tz=Asia%2FShanghai; experiment:homepage_signup_flow=eyJ2ZXJzaW9uIjoiMSIsInJvbGxPdXRQbGFjZW1lbnQiOjM1LjE2NzQ2NjU3Nzg3OTk1Niwic3ViZ3JvdXAiOm51bGwsImNyZWF0ZWRBdCI6IjIwMjAtMDMtMThUMDI6MDQ6MjMuODA4WiIsInVwZGF0ZWRBdCI6IjIwMjAtMDMtMjVUMDQ6MTk6MTUuNjA5WiJ9; user_session=jk2HfEj_4gWfU8V_4dvps7naVFFB_R0aUn4_mVrdxnQWy9u7; __Host-user_session_same_site=jk2HfEj_4gWfU8V_4dvps7naVFFB_R0aUn4_mVrdxnQWy9u7; logged_in=yes; dotcom_user=2829507692; _gh_sess=x0LIdSUTKSwhKICq0QYKsXlDJULU%2BjhBdrK8NzsFYwNIUOHV0gYsMgjLZ%2B8YgTBoSp%2FjMZXHhuMfdD4dr7sqV%2F1IF%2BA0GnYV6J%2BsyyoMxpoz%2BVOdYGWqUi4p5KOIxm6VAOyePx6fEM21VAGMdEqq9EXErfH0n3j81aFFQeKYv3TgkEWqpYbD6DNKWrUOB%2FrbwmyND0z%2BdjrTLDE6YbZnwZwEoaiIZUhd6Rd265uMBD%2B38uNc7jHQRl1TVrfPwHTHXi%2BfE4LSzMOZalVQgoNlGxi0o0QXwa%2F12pt97CFIUjnSIqYwBEEVkl81pVBhjVzkKWQsKLPaSArMJ3wDPBKHegQCRLZ3u2lMa2%2BZTLKnOsA20%2BX9Z%2B2DdRPL9UHusnUME%2F77KC4V%2FNrHMKnPkLC2dpZFojKSZscTpjBB4PeYF4KV84sMOMrxQlHetWDKN8%2BcjSuHPOGdf2qHq67AbyaRsoyFK3T2cQocIqJh9pYEQwmnm%2FasWoP82PsAn%2FbujQY%2BzJq1iVWxVUCH0nc5mShuwJg0AJBjAiaFwSvCjWF5eUFYmKTA9Bk%2FpH254MbDb8ofJsWJs6m1oycxEuJogMHkxZuIrWGIQezG%2BBYODyTJOco4oGRp11dVTPZLXTj3Vet0pwvL749B8hfmskK%2F4w2mvErIoxxe6yy1u0kgwgq4xIdacgwm0I7ZUQC6ak0cGNfOeomjoTSPNLT0DZoUFW4WSjhiGgxIiUowPFB9PQ9FCvxrw8%2FyV0foedzTKQVZUnru7Ik4XkYpKakmfzZRPn5soED4XFgJVmzTB4xVxQSHNzsDgwBWupZYxE5dcYitWVr3OrMYAeqzpc%2BVbEs8%2BtWNpKDlJDOMYQffasdfsqwGexThnNYlj2IvnIz0aQydEva%2FNcZNlHOiEaD%2BN8xdMyqd2GTydT1LjkizWv4SofUNjroCj3mgggH2hCcOwRUhcYUJZt8Z6gW7JYiLCxQqnjVrJBc%2Bw2dgg1scohQhZ6PXkk5IqvX3p2mP2Xq967TEqr4bqntFcARsTUM4bT54D81XHiS6g1Rue0QmXu3pxe%2BEiMpoptbMRcQFsPQqE8PhweZKCL9ZOW0637rmt4qVNuQdvfGi9N2Bs9aO4PjDk%2Brrj5tWhSSzdCRUbYWzhtNj9CXImyQZoTZ7aPKrgRd2tjiEl5l61uPfdAvd%2FXv4dKxXbUlIb3TLhNsmJExDj7CoSiysaKwluM4D2Ggbk9xqtvSI9g57PweEA%2BhoxnjZKI0It65ZgZ5bIX7ipEEAo14uLPsqGut6ittBEp1UT5xELjUaM6LPto%2F9IPLlG4U8mdb3u7xx%2BuTakRu7yfbabDUkv0QXY9nsg3u27eTg097WErlgeB7jqf%2Flc%2Ft8laI%2B641xqA2kKKcr38PYwrkbySJyf5TMjgLop6qFCo738w%2B8J409OIEqNREN0IoW0DrfELoHmAkhMAYyzY2Yynbs3973wyyOTZUwNvm4K0mQQ%3D%3D--07oaTkbSmNfGWujT--xcmABMjlD5SJ9u8LnSFp%2Bw%3D%3D'
cookies_dic={item.split('=')[0]:item.split('=')[1]for item in cookies.split('; ') }
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
}
url = 'https://github.com/'
res = requests.get(url, headers=headers,cookies=cookies_dic).content.decode('utf-8')
if 'username' in res:
print('login True')
1.9、通过构建data字典+Session对象,登录github
1.9.1、通过分析url(https://github.com/session)可知,发送post请求时需要传递以下参数。
commit: Sign in
authenticity_token: 9Ek9mN5qMK7Mr3DS3goFGj1zJcsywLXMA6eLMoZ3fLaW8z4SXuc6Qugv6H2/gyvfjAVOaqxpxHKvCVkUQa1SZg==
login: username
password: password
webauthn-support: supported
webauthn-iuvpaa-support: supported
return_to:
required_field_6c85:
timestamp: 1585111598578
timestamp_secret: 79735a7473e5c621225663e9f306bc3f1ea61c3926869e33200415096b3350c6
但是如果我们通过Session对象,先访问登录页面(https://github.com/login),则session对象中会保存一部分cookies数据,则我们只需传递如下几个参数。
commit: Sign in
authenticity_token: 91zJcsywLXMA6eLMoZ3fLaW8z4SXuc6Qugv6H2/gyvfjAVOaqxpxHKvCVkUQa1SZg==
login: username
password: password
而 authenticity_token这个参数可通过访问登录页面,在页面中获取,从而构建data字典完成登录。
1.9.2、代码如下
import requests
import re
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
'Referer': 'https://github.com/',
}
base_url = 'https://github.com/login'
request = requests.Session()
res = request.get(base_url, headers=headers).content.decode('utf-8')
data = {
'commit': 'Sign in',
'authenticity_token': re.search(r'<input type="hidden" name="authenticity_token" value="(.*?)" />', res,re.S).group(1),
'login': 'username',
'password': 'password',
}
login_url = 'https://github.com/session'
res = request.post(login_url, data=data)
# with open('./1.html', 'w', encoding='utf-8') as file: #可打开这个页面,查看是否登录成功。
# file.write(res.text)
if 'username' in res.text: #也可通过关键字,查看是否登录成功。
print('login True')
1.10、使用requests模块中的工具方法,cookiejar对象与字典的相互转换
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
}
url = 'https://www.baidu.com/'
res = requests.get(url=url, headers=headers)
# print(res.cookies) # cookiesjar对象
cookies=requests.utils.dict_from_cookiejar(ress.cookies)
print(cookies) #cookie字典
cookiejar=requests.utils.cookiejar_from_dict(cookies)
#结果
{'BAIDUID': '433C48E13904DF713411B45230041F16:FG=1', 'BIDUPSID': '433C48E13904DF71881E2EB35D80B98E', 'H_PS_PSSID': '1448_31671_21095_32139_31253_32046_32109_26350', 'PSTM': '1593097271', 'BDSVRTM': '0', 'BD_HOME': '1'}
二、代理
2.1、代理作用
- 突破自身IP 访问限制, 访问一些平时不能访问的站点,比如被墙的一些国外网站,甚至是暗网。
- 访问一些单位或团体内部资源: 比如使用教育网内地址段免费代理服务器, 就可以用于对教育网开放的各类FTP 下载上传, 以及各类资料查询共享等服务。
- 提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区, 当有外界的信息通过时, 同时也将其保存到缓冲区中, 当其他用户再访问相同的信息时, 则直接由缓冲区中取屮信息传给用户, 以提高访问速度。
- 隐藏真实IP : 上网者也可以通过这种方法隐藏自己的IP,减少一些麻烦。对于爬虫来说, 我们用代理就是为了隐藏自身IP , 防止自身的被封锁。
2.2、IP分类
2.2.1、按照协议
- FTP 代理服务器:主要用于访问FTP 服务器, 一般有上传、下载以及缓存功能, 端口一般为21 、2121 等。
- HTTP 代理服务器:主要用于访问网页, 一般有内容过滤和缓存功能, 端口一般为80 、8080 、3128 等。
- SSL/TLS 代理:主要用于访问加密网站, 一般有SSL 或TLS加密功能, 端口一般为443 。
- RTSP 代理:主要用于访问Real 流媒体服务器, 一般有缓存功能, 端口一般为554 。
- Telnet 代理:主要用于telnet 远程控制( 黑客人侵计算机时常用于隐藏身份),端口一般为23
- POP3/SMTP 代理:主要用于POP3/SMTP 方式收发邮件, 一般有缓存功能, 端口一般为110 / 25 。
- SOCKS 代理:只是单纯传递数据包, 不关心具体协议和用法, 所以速度快很多, 一般有缓存功能, 端口一般为1080 。SOCKS 代理协议又分为SOCKS4 和SOCKS5 , 前者只支持TCP ,而后者支持TCP 和UDP , 还支持各种身份验证机制、服务器端域名解析等。简单来说,SOCKS4 能做到的SOCKS5 都可以做到, 但SOCKS5 能做到的SOCKS4 不一定能做到。
2.2.2、按照匿名程度分
-
高匿代理: 会将数据包原封不动地转发,服务器把代理IP当作真实ip,安全性最高。数据包如下:
-
REMOTE_ADDR =代理IP HTTP_VIA = 没数值或不显示 HTTP_X_FORWARDED_FOR =没数值或不显示
-
-
匿名代理:服务器知道你在使用代理,但是不知道你的真实IP。数据包显示如下
-
REMOTE_ADDR =最后一个代理服务器IP HTTP_VIA = 代理服务器IP HTTP_X_FORWARDED_FOR=途经代理IP
-
-
透明代理:服务器知道你在使用代理,而且也知道你的真实ip。数据包如下
-
REMOTE_ADDR =最后一个代理服务器IP HTTP_VIA = 代理服务器IP HTTP_X_FORWARDED_FOR=真实IP,途经代理IP
-
2.3、代理获取
- 1、向代理服务器厂商进行购买,一般会提供接口,方便使用,效率高。
- 2、自己从互联网上爬取,由于是免费的,所以效率低。
2.4、代理使用
我这里从西刺代理官网https://www.xicidaili.com/nn/,复制了几个。
1、非加密代理使用
import requests
proxies = {
"http": 'http://218.75.158.153:3128',
"https": "http://116.113.27.170:47849",
}
url = 'http://httpbin.org/get'
res = requests.get(url, proxies=proxies)
print(res.text)
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "max-age=259200",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0",
"X-Amzn-Trace-Id": "Root=1-5e7c389a-3cc713099f9a75d856987e3c"
},
"origin": "218.75.158.153", #在此,我们看到了上面的代理地址
"url": "http://httpbin.org/get"
}
2、加密代理使用,与上面使用方法类似。
#我们需要加用户名与密码,格式如此
proxies = {
"http": "http://user:pass@218.75.158.153/",
}