在之前的文章中我们介绍了一下 opener 应用中的 ProxyHandler 处理器 (代理设置), 本篇文章我们再来看一下 opener 中的 Cookie 的使用.
Cookie 是指某些网站服务器为了辨别用户身份和进行 Session 跟踪, 而储存在用户浏览器上的文本文件, Cookie 可以保持登录信息到用户下次与服务器的会话.
HTTP 是无状态的面向连接的协议, 为了保持连接状态, 引入了 Cookie 机制 Cookie 是 http 消息头中的一种属性, 包括:
Cookie 名字 (Name)
Cookie 的值 (Value)
Cookie 的过期时间 (Expires/Max-Age)
Cookie 作用路径 (Path)
Cookie 所在域名 (Domain),
使用 Cookie 进行安全连接 (Secure).
前两个参数是 Cookie 应用的必要条件, 另外, 还包括 Cookie 大小 (Size, 不同浏览器对 Cookie 个数及大小限制是有差异的).
Cookie 由变量名和值组成, 根据 Netscape 公司的规定, Cookie 格式如下:
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
Cookie 应用
Cookies 在爬虫方面最典型的应用是判定注册用户是否已经登录网站, 用户可能会得到提示, 是否在下一次进入此网站时保留用户信息以便简化登录手续.
- import urllib.request
- # 1. 构建一个已经登录过的用户的 headers 信息
- headers = {
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) ApplewebKit/537.36 (Khtml, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
- "Cookie": "anonymid=jurpmxe9-orl7u3;"
- "depovince=BJ;"
- "_r01_=1;"
- "JSESSIONID=abcwYLyIY7VNIhCDVWcPw;"
- "jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e|c13c37f53bca9e1e7132d4b58ce00fa3|1484060607478|1|1484060607173;"
- "jebecookies=f1fd29c4-bd08-4d66-8834-72e42b70d2cb|||||;"
- "ick_login=0f790ea2-c8bf-4d64-a394-36745febeb26;"
- "_de=622DE758381206EB340E4CEC836F3769696BF75400CE19CC;"
- "p=7e50f3fe10ca320e36dae001c72d392d3;"
- "ap=327550029;"
- "first_login_flag=1;"
- "ln_uact=562352353@qq.com;"
- "ln_hurl=http://hdn.xnimg.cn/photos/hdn121/20120930/2035/h_main_hcDy_40fc000002d91375.jpg;"
- "t=d7c6ae064b81ae15f5b91f5897dc61553;"
- "societyguester=d7c6ae064b81ae15f5b91f5897dc61553;"
- "id=485439163;"
- "xnsid=bc995dc8;"
- "ver=7.0;"
- "loginfrom=null"
- }
- # 2. 通过 headers 里的报头信息 (主要是 Cookie 信息), 构建 Request 对象
- request = urllib.request.Request("http://www.renren.com", headers=headers)
- # 3. 直接访问 renren 主页, 服务器会根据 headers 报头信息 (主要是 Cookie 信息), 判断这是一个已经登录的用户, 并返回相应的页面
- response = urllib.request.urlopen(request)
- # 4. 打印响应内容
- print(response.read().decode("utf-8"))
但是这样做太过复杂, 我们先需要在浏览器登录账户, 并且设置保存密码, 并且通过抓包才能获取这个 Cookie, 那有么有更简单方便的方法呢?
cookielib 库 和 HTTPCookieProcessor 处理器
在 Python 处理 Cookie, 一般是通过 http 模块的 cookiejar 模块和 urllib 模块的 HTTPCookieProcessor 处理器类一起使用.
cookiejar 模块: 主要作用是提供用于存储 cookie 的对象
HTTPCookieProcessor 处理器: 主要作用是处理这些 cookie 对象, 并构建 handler 对象.
- import urllib.request
- import urllib.parse
- from http import cookiejar
- # 1. 构建一个 CookieJar 对象实例来保存 cookie
- cookie = cookiejar.CookieJar()
- # 2. 使用 HTTPCookieProcessor() 来创建 cookie 处理器对象, 参数为 CookieJar() 对象
- cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
- # 3. 通过 build_opener() 来构建 opener
- opener = urllib.request.build_opener(cookie_handler)
- # 4. addheaders 接受一个列表, 里面每个元素都是一个 headers 信息的元祖, opener 将附带 headers 信息
- opener.addheaders = [("User-Agent",
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36")]
- # 5. 需要登录的账户和密码
- data = {"email": "562352353@qq.com", "password": "chen562352353"}
- # 6. 通过 urlencode() 转码
- postdata = urllib.parse.urlencode(data).encode("utf-8")
- # 7. 构建 Request 请求对象, 包含需要发送的用户名和密码
- request = urllib.request.Request("http://www.renren.com/PLogin.do", data=postdata)
- # 8. 通过 opener 发送这个请求, 并获取登录后的 Cookie 值,
- opener.open(request)
- # 9. opener 包含用户登录后的 Cookie 值, 可以直接访问那些登录后才可以访问的页面
- response = opener.open("http://www.renren.com/485439163")
- # 10. 打印响应内容
- print(response.read().decode("utf-8"))
模拟登录要注意几点:
登录一般都会先有一个 HTTP GET, 用于拉取一些信息及获得 Cookie, 然后再 HTTP POST 登录.
HTTP POST 登录的链接有可能是动态的, 从 GET 返回的信息中获取.
password 有些是明文发送, 有些是加密后发送. 有些网站甚至采用动态加密的, 同时包括了很多其他数据的加密信息, 只能通过查看 JS 源码获得加密算法, 再去破解加密, 非常困难.
大多数网站的登录整体流程是类似的, 可能有些细节不一样, 所以不能保证其他网站登录成功.
来源: https://www.cnblogs.com/weijiutao/p/10750235.html