浏览器用一行JS代码导出cookies.txt,Python的requests库导入cookies格式化为字典格式

在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:”。

正确的姿势是:先在地址栏里粘贴上面的代码,然后在地址栏的按Home键回到代码的最前面,再手动敲入 javascript: (注意带冒号而且是半角的),敲回车,这样就能导出cookies.txt到指定的目录。

浏览器如果没有弹出保存文件的对话框,是因为浏览器设置了自动保存到默认的目录,如C:\Users\Administrator\Downloads\。如果需要浏览器每次保存文件都要咨询你保存到哪里,就要先在浏览器的设置里找到下面的设置:

 第二步:Python的requests库导入cookies.txt为字典格式

Requests库的session可以导入cookies,要求cookies必须是字典格式。

上面在浏览器里输入JS代码导出的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)

2月27日更新:用re库正则表达式的findall完美解决

今天我调试了本文代码几次,发现当cookies包含嵌套信息中又有“=”的情况下,上面的代码解析出错。比如cookies有一项内容为:

param={"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","token":"","url":"https://xxxxxxx.com/login/source=xxxxxxx"};

这是一个嵌套了字典格式的cookies信息。param后面有等号,花括号里面也嵌套了一个等号,如果按上面的代码先找等号拆分,再转换字典格式会出错。

我们的目的很简单,就是要在cookies信息里找“xxx = xxxxxxxx”来拆分。调试了多次,最后只有re库的正则表达式才能解决。这个正则表达式很难调,我弄成下面的代码就能成功拆分出来。

 ([a-zA-Z0-9_]+)=((?:{[^{}]*}|[^;]*)+) 

因此代码更新如下:

import requests
import re

def cookies_to_dict(cookie_str):
    matches = re.findall(r'([a-zA-Z0-9_]+)=((?:{[^{}]*}|[^;]*)+)', cookie_str)
    result = {}
    for i in matches:
        result.update({i[0]:i[1]})
    return result



if __name__ == '__main__':
    # 载入cookies.txt
    with open(r'C:\Users\Administrator\Downloads\cookies.txt', 'r', encoding='utf-8') as f:
        cookie_str = f.read()

    # 把cookies转换为字典格式
    cookies_dict = cookies_to_dict(cookie_str)

    # 初始化requests的Session
    se = requests.Session()
    se.cookies.clear()
    # 先清空Session的cookies,再导入cookies_dict
    se.cookies.update(cookies_dict)

假设载入cookies.txt,cookie_str字符串内容是'mediav={"_refnf":0};ID=ed5026a06; param={"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","token":"","url":"https://xxxxxxx.com/login/source=xxxxxxx"}; cookie_referer=; token=validation:token'

经过上述改进的cookies_to_dict()函数转换为字典格式cookies_dict内容为:

{
    'mediav': '{"_refnf":0}',
    'ID': 'ed5026a06',
    'param': '{"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","token":"","url":"https://xxxxxxx.com/login/source=xxxxxxx"}',
    'cookie_referer': '',
    'token': 'validation:token'
}

猜你喜欢

转载自blog.csdn.net/Scott0902/article/details/129166907