使用 cookielib 库和 HTTPCookieProcessor 模拟登录

  • Cookie 是指网站服务器为了辨别用户身份和进行 Session 跟踪,而存储在用户浏览器上的文本文件,Cookie 可以保持登录信息到用户下次与服务器的会话。
  • 这里以人人网为列。人人网中,要访问某个人的主页,必须先登录才能访问,登录说白了就是要有 cookie 信息。那么如果我们想要用代码的方式访问,就必须要有正确的 cookie 信息才能访问。解决方案有两种,第一种是使用浏览器访问,然后将 cookie 信息复制下来,放在 headers 中。实例代码如下:
from urllib import request

headers = {
	'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
	'Cookie':'anonymid=k8fmzwpc-s6rv4y; depovince=GW; _r01_=1; JSESSIONID=abcSTPRpQpHjndIcOSVex; ick_login=4fb2d067-1da0-4e57-9a1d-49253222fe5e; taihe_bi_sdk_uid=11fcb71e12e5d3f9836970ee286569b9; taihe_bi_sdk_session=17c27e311d06f72304383b502a42d52c; loginfrom=null; jebe_key=6a81771e-71e1-4ece-8021-81658034b3a4%7C0bc825282c148c271f4ee4d968a62345%7C1585643279685%7C1%7C1585643280627; jebe_key=6a81771e-71e1-4ece-8021-81658034b3a4%7C0bc825282c148c271f4ee4d968a62345%7C1585643279685%7C1%7C1585643280630; XNESSESSIONID=ed8b1487fa6d; __gads=ID=bbad2bbe01c69282:T=1585643366:S=ALNI_MbD5mYa3DidCrsxsqi1GtTvyBrY_Q; wp_fold=0; jebecookies=d5d9bb57-7a69-4211-9c83-ec72153532f6|||||'
}
# url 未写完整,代码只做演示用,所以运行结果不是想要的
# 这里的 url 应该是你已经登录后的页面,Cookie 值也是在登录后的页面信息里提取
url = 'http://www.renren.com'
req = request.Request(url = url,headers = headers)
resp = request.urlopen(req)
with open('renren.html','w',encoding = 'utf-8') as fp:
	# write 函数必须写入一个 str 的数据类型
	# resp.read() 读出来的是一个 bytes 数据类型
	# bytes -> decode -> str
	# str -> encode -> bytes
	fp.write(resp.read().decode('utf-8'))
  • 这种方式是最简单粗暴的,但是每次在访问需要 cookie 的页面都要从浏览器中复制 cookie比较麻烦。在 python 处理 cookie,一般是通过 http.cookiejar 模块和 urllib 模块的HTTPCookieProcessor 处理器类一起使用。http.cookiejar 模块主要作用是提供用于存储 cookie 的对象。而 HTTPCookieProcessor 处理器主要作用是处理这些 cookie 对象,并构建 handler 对象。

1、http.cookiejar 模块

  • 该模块主要的类有:CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。这是个类的作用分别如下:

CookieJar

管理 HTTP cookie 值、存储 HTTP 请求生成的 cookie、向传出的 HTTP 请求添加 cookie 对象。整个 cookie 都存储在内存中,对 CookieJar 实例进行垃圾回收后 cookie 也将消失

FileCookieJar(filename,delayload=None,policy=None)

从 CookieJar 派生而来,用来创建 FileCookieJar 实例,检索 cookie 信息并将 cookie 存储到文件中。filename 是存储 cookie 文件的名字。delayload 为 True 时,支持延迟访问文件,即只有在需要时才读取文件或在文件中存储数据

MozillaCookieJar(filename,delayload=None,policy=None)

从 FileCookieJar 派生而来,创建与 Mozilla 浏览器

LWPCookieJar(fiilename,delayload=None,policy=None)

从 FileCookieJar 派生而来,创建与 libwww-per 标准的 Set-Cookie3 文件格式兼容的 FileCookieJar 实例

  • 利用 http.cookiejar 和 request.HTTPCookieProcessor 登录人人网。相关代码如下:
from urllib import request
from urllib import parse
from http.cookiejar import CookieJar

headers = {
	'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}

def get_opener():
	# 1. 登录
	# 1.1 创建一个 cookiejar 对象
	cookiejar = CookieJar()
	# 1.2 使用 cookiejar 创建一个 HTTPCookieProcessor 对象
	handler = request.HTTPCookieProcessor(cookiejar)
	# 1.3 使用上一个 handler 创建一个 opener
	opener = request.build_opener(handler)
	# 1.4 使用 opener 发送登录信息,包括登录的用户名(邮箱)和密码
	return opener

def login_renren(opener):
	data = {
		'email':"xxxxxxxx",
		'password':"xxxxxxxx"
	}
	req = request.Request('需要进行登录的页面 url',headers = headers,data = parse.encode(data).encode('utf-8'))
	opener.open(req)		# 返回的数据不作处理,目的只是为了获取 cookie,已经存储到内存了


def visit_profile(opener):
	# 2. 访问个人主页
	url = '登录后的页面 url'
	# 获取个人主页信息页面的时候,不要新建一个 opener,而是应该使用之前的 opener ,因为之前那个 opener 已经包含了登录的 cookie 信息
	req = request.Request(url,headers = headers)
	resp = opener.open(req)
	with open('xxx.html','w',encoding = 'utf-8') as pf:
		pf.write(resp.read().decode('utf-8'))

if __name__ == '__main__':
    opener = get_opener()
	login_renren(opener)
	visit_profile(opener)

2、保存 cookie 到本地

  • 保存 cookie 到本地,可以使用 cookiejar 的 save 方法,并且需要指定一个文件名,代码如下:
from urllib import request
from http.cookiejar import MozillaCookieJar

cookiejar = MozillaCookieJar("cookie.txt")
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)

resp = opener.open('http://www.baidu.com')
# 上面已经指定文件名,save 里面就不在需要指定
cookiejar.save()
# cookiejar.save(ignore_discard = True)		保存过期的 cookie 信息

3、从本地加载 cookie

  • 从本地加载 cookie,需要使用 cookiejar 的 load 方法,并且也需要指定方法,代码如下:
from urllib import request
from http.cookiejar import MozillaCookieJar

cookiejar = MozillaCookieJar("cookie.txt")
cookiejar.load()
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)

resp = opener.open('http://www.baidu.com')
for cookie in cookiejar:
	print(cookie)