欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载

程序员文章站 2022-07-14 17:00:37
...

一、cookie基本概念介绍

cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载
cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载

二、cookie模拟登录

""""
访问一个需要登录的网站需要加入cookie在headers中

以访问知乎热榜https://www.zhihu.com/hot为例
不登录无法访问热榜的内容 :从程序控制台输出的网页内容中ctrl+F查找网页中复制的内容 
发现找不到,即使我们在headers中加了User-Agent也访问不了热榜内容

解决方法一: headers中加入从https://www.zhihu.com/hot网页复制的cookie
    注意仅仅在 headers中加入从网页https://www.zhihu.com/hot中
    复制的referer :https://www.zhihu.com/仍然得不到网页具体内容
    必须要加cookie,加了之后referer加不加都可以
解决方法二: 使用http.cookiejar模块
	方法一缺点在于每次都要手动复制cookie
"""
方法一:

from urllib import request

url = 'https://www.zhihu.com/hot'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
    'cookie': '_zap=6254847e-05fc-47da-897d-32799a38c440; _xsrf=LMrVYFcjhUeQXgQwrldY9c5AMfmDkHh9; d_c0="AABe0WtVNRKPTuPNiS6nb1l79WQcZ8BVFKQ=|1605596807"; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1605597577,1605598205,1605616975,1605855550; SESSIONID=ac9jlFTsWbmfmjKTeSn6uMsaphHjGeQwHEWWAswMsoh; JOID=V10cA0j4RCKWAYRkbv1CPsJV2VdwmSsS_2vCPBSpJkP5b-gvNrUon8wHiGFk9L4tUVcrRbcGrsjOvtAgJEnd3gg=; osd=W1gRB0P0QS-SCohhY_lJMsdY3Vx8nCYW9GfHMRCiKkb0a-MjM7gslMAChWVv-LsgVVwnQLoCpcTLs9QrKEzQ2gM=; capsion_ticket="2|1:0|10:1605855613|14:capsion_ticket|44:OWUwMjdjYWJlNDJhNDZlZDlmMWVmODg5YTJiMjYxMmU=|a8eccf9506532bc47f26af3714887c4f5b82829ece6297f19a2e9e5fb66e1a04"; z_c0="2|1:0|10:1605855647|4:z_c0|92:Mi4xZG45MUF3QUFBQUFBQUY3UmExVTFFaVlBQUFCZ0FsVk5ucmVrWUFBSXhxNmdEYUo2NDRKVVRuZDM2bkRIY1RXSUJB|93924560630b1f1de724c39f20715724796813992cefa5bf443a44341eb9b547"; unlock_ticket="ADBA8ak6jAomAAAAYAJVTaZwt18cff3tVnbut8NYHQqBUQNImnP8Tg=="; tst=h; tshl=; Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49=1605856062; q_c1=292df6e7c2104f348df3ce2c4656057e|1605856064000|1605856064000; KLBRSID=cdfcc1d45d024a211bb7144f66bda2cf|1605856297|1605855546',
    'referer': 'https://www.zhihu.com/'

}
req = request.Request(url, headers=headers)
with request.urlopen(req) as resp:
    print(resp.read().decode('utf-8'))

方法二:见http.cookiejar模块介绍

三、http.cookiejar模块

这一部分会基本的使用就行 不用太深入了解
http.cookiejar模块中主要的类有两个基本类,两个派生类:
	(1)CookieJar(policy=None)
		作用:
			管理cookie值、存储http请求生成的cookie、向传出的http请求添加cookie对象
		注意:整个cookie都存储在内存中 对CookieJar实例进行垃圾回收后cookie也将丢失
		CookieJar对象有些方法如增加cookie header,extract cookie
	(2)FileCookieJar(filename,delayload=None,policy=None)
		作用:
			创建FileCookie实例、检索cookie信息并存储cookie到文件
		参数列表:
			filename:储存cookie的文件名
			delayload:为True时支持延迟访问文件 即只有在需要时才读取文件或文件中的数据
		FileCookieJar对象实现以下方法
			(1)把cookie保存到文件
				save(filename=None,ignore_discard=False,ignore_expires=False)
				ignore_discard:是否保存即将丢弃的cookie,为true保存 为false不保存
				ignore_expires:是否保存已经过期的cookie,为true保存 为false不保存
				同时若指定的文件若已存在,文件原有内容被本次保存覆盖
			(2)从文件中读取cookie
				load(filename=None,ignore_discard=False,ignore_expires=False)
		FileCookieJar有两个子类:
		它们实现了具体的把cookie内容保存为文件的方法。只是这两个类对应的标准不同而已。
		(1)MozillaCookieJar(filename,delayload=None,policy=None)
			创建与Mozilla浏览器cookie.txt兼容的FileCookiejar实例
		(2)LWPCookieJar(filename,delayload=None,policy=None)
			创建与libwww-perl标准的Set-Cookie3文件格式兼容的FileCookiejar实例
			即以the libwww-perl library’s Set-Cookie3 文件形式把cookie存取到磁盘上

cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载
cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载

(1)http.cookiejar实现模拟登录

"""
以美食杰个人美食空间网页'https://www.meishij.net/?from=space_block'为例(访问该网也需要登录 )
1、登录
    1.1、创建cookiejar对象
    1.2、使用cookiejar创建HTTPCookieProcess对象handler
    1.3、使用上一步创建的handeler通过build_opener创建一个opener
    1.4、使用opener发送登录请求(账号密码)
        注意这里需要从网页找到登录的网页url,这并不是我们上面美食杰个人没事空间网页的那个url
        login_url = 'https://i.meishi.cc/login_t.php?username=15611778520&login_type=1&password=130967'
        浏览器中填写账号密码并通过network抓包找到登录的login包 复制request header中的User-Agent ,request url ,和我们输入的账号密码

        这里我们看到login_url中包含了数据username passward login_type(表示是账号密码登录还是手机验证码登录)
        因此我们本次浏览器的登录请求方式是get!
2、访问

因此直接爬虫一个需要登录的网页 就是先模拟登录再访问

"""
from http.cookiejar import CookieJar
from urllib import request, parse

login_url = 'https://i.meishi.cc/login_t.php?username=15611778520&login_type=1&password=130967'

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

# 1、登录
cookiejar = CookieJar()
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)

req = request.Request(login_url, headers=headers)
opener.open(req)
# resp = opener.open(req)
# 注意在opener.open才是发送登录请求,发送之后服务器会返回一个cookie,此时这个cookie就存在opener里面的
# 因为在login_url中已经包含了username passward等信息
# 另外,并不是 req = request.Request(login_url, headers=headers)发送登录请求 这只是构造一个请求对象Request

# 至此登录完成 当然我们并不需要登录页面的数据信息因此可以不用resp = opener.open(req)获取返回值resp
# 直接opener.open(req)即可

# 同时这里的opener的用法和设置代理ProxyHandler完全一样 ProxyHandler,一个是HTTPCookieProcessor
# 都是先创建一个handler 再以此handler去build一个opener
# 然后opener.open一个url或者是urllib.request.Request对象
# (具体看是get还是post以及是否添加包头,一般不管是get还是post都是open一个Request对象,因为一般都需要在headers中加入User-Agent)
# 设置代理ProxyHandler参见代码 urllib/ProxyHandler()设置代理

# 当然如果是post方式 则我们需要手动添加data
# 通过urlencode()把字典类型的data(username passward)进行zhuan成str
# 再通过bytes(str,encoding)str转bytes  或者直接str.encode()
# 最后传入到request.Requset()的data参数中,如下

# data = parse.urlencode({
#     'username': 'xxx',
#     'passward': 'xxx',
#     'login_type': '1'
# })
# req = request.Request(login_url, data=data.encode('utf-8'), headers=headers)

# 2、访问
url = 'https://www.meishij.net/?from=space_block'
req = request.Request(url, headers=headers)
with opener.open(req) as resp:
    print(resp.read().decode('utf-8'))
# 注意这里的url不再是login_url

(2)保存cookie到本地文件

"""
注意上述内容通过cookiejar = CookieJar()创建cookiejar实例,
我们的cookie信息是自动保存到内存中的,当对CookieJar实例进行垃圾回收后cookie也将丢失
如果要把保存cookie到本地 创建cookiejar实例稍有不同 需要使用http.cookiejar模块下的MozillaCookieJar类 而不再是CookieJar类

另外保存cookie到本地时
若在使用MozillaCookieJar创建cookiejar实例时指定了文件名 则save时不用指定文件名
如果创建时没有指定文件名则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()
之前在设置代理是用网站http://httpbin.org/查看发送给请求的ip
同时该网站还支持设置cookie
将上面代码的url换成我们在网页设置cookie后生成的url
"http://httpbin.org/cookies/set/BUPT_NAME/computer_science"
这个url在cookie设置页Request URL栏 如下图

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://httpbin.org/cookies/set/BUPT_NAME/computer_science")
cookiejar.save()

执行代码发现cookie.txt文件存的还是我们刚才访问百度网页的cookie,
没有存储我们刚才设置的cookie:
 "cookies": {
    "BUPT_NAME": "computer_science"
  }

cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载
cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载

原因在于 我们设置的cookie已经过期 可通过点击chrome左上角看到如下图
‘到期时间:浏览会话结束时’
因此需要设置save的参数可实现保存过期cookie

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://httpbin.org/cookies/set/BUPT_NAME/computer_science")
cookiejar.save(ignore_discard=True,ignore_expires=True)

执行代码后查看cookie.txt保存设置的cookie成功

cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载

cookie(一)http.cookiejar模块:两种方法实现模拟登录、cookie本地保存和加载

(3)加载和读取cookie

# cookie文件加载读取
cookiejar = MozillaCookieJar('cookie.txt')
cookiejar.load()
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
url = "http://httpbin.org/cookies/set/BUPT_NAME/computer_science"
resp = opener.open(url)
for cookie in cookiejar:
    print(cookie)

运行结果
<Cookie BUPT_NAME=computer_science for httpbin.org/>
相关标签: 爬虫学习 爬虫