在Python进行爬虫时,如果仅使用requests库打开某个网页,requests的session.cookies保存的cookies信息少得可怜,有时cookies甚至是空白!但浏览器里打开同一个网页,cookies信息非常详尽,比如浏览器的cookies保留了登录之后的状态信息,为了Python免登录快速进入某个网页,我们需要先将浏览器的网页cookies导出,然后在Python里使用requests库导入cookies。
第一步:浏览器导出文本格式的cookies.txt
在浏览器的地址栏里可以输入以下JS代码,快速导出当前页面的cookies为一个文本文件cookies.txt:
javascript: (function() { const a = document.createElement('a'); a.href = 'data:text/plain,' + document.cookie; a.download = 'cookies.txt'; a.target = '_blank'; a.style.display = 'none'; document.body.appendChild(a); a.click(); setTimeout(function() { document.body.removeChild(a); }, 100);})();
注意:不能直接粘贴以上的代码,否则浏览器会自动屏蔽掉开头的“javascript:”。
正确的姿势是:先在地址栏里输入或粘贴 javascript: (注意带冒号而且是半角的),然后再粘贴上面的JavaScript:后面的代码,敲回车,这样就能导出cookies.txt到指定的目录。
浏览器如果没有弹出保存文件的对话框,是因为浏览器设置了自动保存到默认的目录,如C:\Users\Administrator\Downloads\。如果需要浏览器每次保存文件都要咨询你保存到哪里,就要先在浏览器的设置里找到下面的设置:
第二步:Python的requests库导入cookies.txt为字典格式
Requests库的session可以导入cookies,要求cookies必须是字典格式。
上面导出的cookies.txt只有一行,举个例子:
mediav={"_refnf":0};ID=ed5026a06; param={"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","token":""}; cookie_referer=; token=validation:token
这只是为了方便展示而举个简单的例子,实际的cookies字符串会比这个更长。
前辈的做法是按分号来分割字符串,然后用dict()转成字典格式。但遇到这个例子,user-agent值也有分号,如果简单地按分号分割,分割出来再转字典格式会出错。
我的做法是:按等号分割,然后再去除多余的分号。
with open('cookies.txt', encoding = 'utf-8') as f:
cookies = f.read()
'''
载入cookies.txt,假设cookies内容是:'mediav={"_refnf":0};ID=ed5026a06; param={"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","token":""}; cookie_referer=; token=validation:token'
'''
l1=cookies.split('=')
print(l1)
'''
输出:
['mediav', '{"_refnf":0};ID', 'ed5026a06; param', '{"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","token":""}; cookie_referer', '; token', 'validation:token']
'''
可以看到 l1 列表的偶数元素混杂了键和值,需要去除多余的分号,就要把它们拆散,下面是我改进的代码:
def cookies_to_dict(cookies):
l1=l2=[]
l1=cookies.split('=')
for i in l1:
if ';' in i:
# 如果字符串存在分号就从后往前找分号来分割
ss = i.rpartition(';')
# rpartition()的作用就是从后往前找,返回三个元素的元组
# 第一个为分隔符左边的子串,第二个为分隔符本身,第三个为分隔符右边的子串
# 因此这里使用extend一次添加ss[0]和ss[2]的子串
l2.extend([ss[0].strip(), ss[2].strip()])
# strip()的作用是清除子串左端和右端的多余的空格
else:
l2.append(i.strip())
c_dict={}
for i in range(0,len(l2),2):
c_dict.update({l2[i]:l2[i+1]})
return c_dict
cookie_dict = cookies_to_dict(cookies)
print(cookie_dict)
'''
输出:
{'mediav': '{"_refnf":0}', 'ID': 'ed5026a06', 'param': '{"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","token":""}', 'cookie_referer': '', 'token': 'validation:token'}
'''
这样cookies.txt就格式化成字典格式了。接下来就可以导入进requests的session里。
import requests
se = requests.Session()
se.cookies.clear()
# 先清空Session的cookies,再导入cookies_dict
se.cookies.update(cookies_dict)