python 爬虫如何正确的使用cookie


Posted in Python onOctober 27, 2020

很多时候,我们要查看的内容必须要先登录才能找到,比如知乎的回答,QQ空间的好友列表、微博上关注的人和粉丝等。要使用爬虫直接登录抓取这些信息时,有一个不太好解决的难题,就是这些网站设置的登录规则以及登录时的验证码识别。不过,我们可以想办法绕过去,思路是这样的:先使用浏览器登录,从浏览器获取登录后的“凭证”,然后将这个“凭证”放到爬虫里,模拟用户的行为继续抓取。这里,我们要获取的凭证就是cookie信息。

这次我们尝试使用python和cookie来抓取QQ空间上的好友列表。使用的工具是FireFox浏览器、FireBug和Python。

获取cookie

打开FireFox浏览器,登录QQ空间,启动FireBug,选择FireBug中的Cookies页签,点击页签中的cookies按钮菜单,选择“导出本站点的cookie”即可完成cookie的导出。

python 爬虫如何正确的使用cookie

导出cookie会以一个名为cookies.txt文本文件形式存在。

程序实现

然后我们会使用获取的cookie新建一个opener来替换之前请求时使用的默认的opener。将获取的cookies拷贝到程序目录下,编写脚本如下:

#!python
# encoding: utf-8
from http.cookiejar import MozillaCookieJar
from urllib.request import Request, build_opener, HTTPCookieProcessor
 
DEFAULT_HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"}
DEFAULT_TIMEOUT = 360
 
 
def grab(url):
    cookie = MozillaCookieJar()
    cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
    req = Request(url, headers=DEFAULT_HEADERS)
    opener = build_opener(HTTPCookieProcessor(cookie))
    response = opener.open(req, timeout=DEFAULT_TIMEOUT)
    print(response.read().decode('utf8'))
 
 
if __name__ == '__main__':
    grab(<a href="http://user.qzone.qq.com/QQ号/myhome/friends" rel="external nofollow" >http://user.qzone.qq.com/QQ号/myhome/friends</a>)

因为我们使用的是FireFox浏览器导出的cookie文件,所以这里使用的cookieJar是MozillaCookieJar。

执行脚本…然而报错了:

Traceback (most recent call last):
  File "D:/pythonDevelop/spider/use_cookie.py", line 17, in <module>
    start()
  File "D:/pythonDevelop/spider/use_cookie.py", line 9, in start
    cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
  File "D:\Program Files\python\python35\lib\http\cookiejar.py", line 1781, in load
    self._really_load(f, filename, ignore_discard, ignore_expires)
  File "D:\Program Files\python\python35\lib\http\cookiejar.py", line 2004, in _really_load
    filename)
http.cookiejar.LoadError: 'cookies.txt' does not look like a Netscape format cookies file

问题出在cookies文件上,说是不像一个Netscape格式的cookie文件。不过也好解决,只需要在cookies文件开始一行添加如下内容即可:

# Netscape HTTP Cookie File

通过这行内容提示python cookie解析器这是一个FireFox浏览器适用的cookie。

再次执行,还是会报错,因为比较长我就只贴关键的部分出来:

http.cookiejar.LoadError: invalid Netscape format cookies file 'cookies.txt': '.qzone.qq.com\tTRUE\t/\tFALSE\tblabla\tdynamic'

意思是cookie中某些行存在格式错误。具体错在哪儿,需要先了解下FireFox浏览器的cookie格式。MozillaCookieJar认为每行cookie需要包含以下信息,每条信息以制表符分隔:

名称 domain domain_specified path secure expires name value
类型 字符串 布尔型 字符串 布尔型 长整型 字符串 字符串
说明 域名 适用路径 是否使用安全协议 过期时间 名称

其中domain_specified是什么意思我不很清楚,以后弄明白了再补上。再来看看我们获取的cookie的部分行:

user.qzone.qq.com	FALSE	/	FALSE	814849905_todaycount	0
user.qzone.qq.com	FALSE	/	FALSE	814849905_totalcount	0
.qzone.qq.com	TRUE	/	FALSE	1473955201	Loading	Yes
.qzone.qq.com	TRUE	/	FALSE	1789265237	QZ_FE_WEBP_SUPPORT	0

前两行格式是错误的,后两行格式是正确的。前两行缺少“expires”属性。该怎么办呢——补上就好了呗。在其他的cookie中随意选一个时间补上就OK了。

补全cookie后,再次执行是正常的,没有报错。但是没有如预期的打印出好友信息,因为网址错了。使用firebug可以找出正确的网址:

https://h5.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/friend_ship_manager.cgi?uin=QQ号&do=1&rd=0.44948123599838985&fupdate=1&clean=0&g_tk=515169388

这样就抓取到好友列表了。好友列表是一个json字符串。

python 爬虫如何正确的使用cookie

至于如何解析json,会在下一节进行说明。

动态获取cookie

cookie是有过期时间的。如果想长时间抓取网页,就需要每隔一段时间就更新一次cookie。如果都是从FireFox浏览器来手动获取显得有些笨了。从浏览器获取的cookie只是作为一个入口,之后再进行请求还是要依靠python主动获取cookie。下面是一段获取cookie的程序:

#!python
# encoding: utf-8
from http.cookiejar import CookieJar
from urllib.request import Request, HTTPCookieProcessor, build_opener
 
DEFAULT_HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"}
DEFAULT_TIMEOUT = 360
 
 
def get(url):
    cookie = CookieJar()
    handler = HTTPCookieProcessor(cookie)
    opener = build_opener(handler)
    req = Request(url, headers=DEFAULT_HEADERS)
    response = opener.open(req, timeout=DEFAULT_TIMEOUT)
    for item in cookie:
        print(item.name + " = " + item.value)
    response.close()

在示例程序中演示了如何获取cookie,并打印了cookie的name和value两项属性。通过实例可以看到每次执行http请求都会重新获取cookie,因此可以将我们的程序调整一下:执行第一次请求时使用我们通过浏览器获取的cookie,之后的每次请求都可以使用上次请求时获取的cookie。调整后的程序:

#!python
# encoding: utf-8
from http.cookiejar import MozillaCookieJar, CookieJar
from urllib.request import Request, build_opener, HTTPCookieProcessor, urlopen
 
DEFAULT_HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"}
DEFAULT_TIMEOUT = 360
 
 
def gen_login_cookie():
    cookie = MozillaCookieJar()
    cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
    return cookie
 
 
def grab(cookie, url):
    req = Request(url, headers=DEFAULT_HEADERS)
    opener = build_opener(HTTPCookieProcessor(cookie))
    response = opener.open(req, timeout=DEFAULT_TIMEOUT)
    print(response.read().decode("utf8"))
    response.close()
 
 
def start(url1, url2):
    cookie = gen_login_cookie()
    grab(cookie, url1)
    grab(cookie, url2)
 
 
if __name__ == '__main__':
    u1 = "https://user.qzone.qq.com/QQ号/myhome/friends"
    u2 = "https://h5.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/friend_ship_manager.cgi?uin=QQ号&do=2&rd=0.44948123599838985&fupdate=1&clean=0&g_tk=515169388"
    start(u1, u2)

就这样。

其他

其实在登录QQ空间时使用cookie还有另一种法子——通过观察,也可以在http 请求头中添加cookie信息。

获取请求头中cookie的方式:打开FireFox浏览器,打开FireBug并激活FireBug的network页签,在FireFox浏览器上登录QQ空间,然后在FireBug中找到登录页请求,然后就可以找到请求头中的cookie信息了。

python 爬虫如何正确的使用cookie

将cookie信息整理成一行,添加到请求头中就可以直接访问了。这个方法相对简单,减少了修改cookie文件的步骤。

此外,在一篇博客文章中还找到了直接登录QQ空间的方案。这算是已知最好的法子了,只要腾讯不改变登录规则就能很简单的执行请求获取cookie。不过年代久远,不知规则是否还适用

以上就是python 爬虫如何正确的使用cookie的详细内容,更多关于python 爬虫使用cookie的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python字典基本操作实例分析
Jul 11 Python
PyTorch CNN实战之MNIST手写数字识别示例
May 29 Python
在python下使用tensorflow判断是否存在文件夹的实例
Jun 10 Python
如何利用Python模拟GitHub登录详解
Jul 15 Python
Win10 安装PyCharm2019.1.1(图文教程)
Sep 29 Python
python从zip中删除指定后缀文件(推荐)
Dec 05 Python
Python模块_PyLibTiff读取tif文件的实例
Jan 13 Python
Python 定义只读属性的实现方式
Mar 05 Python
理解Django 中Call Stack机制的小Demo
Sep 01 Python
详解tensorflow之过拟合问题实战
Nov 01 Python
Python Selenium操作Cookie的实例方法
Feb 28 Python
Python基础之tkinter图形化界面学习
Apr 29 Python
python+requests实现接口测试的完整步骤
Oct 27 #Python
python设置中文界面实例方法
Oct 27 #Python
使用python-cv2实现Harr+Adaboost人脸识别的示例
Oct 27 #Python
基于python实现坦克大战游戏
Oct 27 #Python
Django xadmin安装及使用详解
Oct 26 #Python
python实现网页录音效果
Oct 26 #Python
python实现录音功能(可随时停止录音)
Oct 26 #Python
You might like
用PHP和MySQL保存和输出图片
2006/10/09 PHP
PHP生成各种常见验证码和Ajax验证过程
2016/01/10 PHP
javascript 数组的方法集合
2008/06/05 Javascript
HTA版JSMin(省略修饰语若干)基于javascript语言编写
2009/12/24 Javascript
jQuery实现的超简单点赞效果实例分析
2015/12/31 Javascript
JavaScript小技巧整理篇(非常全)
2016/01/26 Javascript
JS代码实现根据时间变换页面背景效果
2016/06/16 Javascript
JavaScript实战之带收放动画效果的导航菜单
2016/08/16 Javascript
jQuery实现鼠标经过时高亮,同时其他同级元素变暗的效果
2016/09/18 Javascript
JavaScript三种绑定事件方式及相互之间的区别分析
2017/01/10 Javascript
Angular2 PrimeNG分页模块学习
2017/01/14 Javascript
websocket+node.js实现实时聊天系统问题咨询
2017/05/17 Javascript
Three.js利用dat.GUI如何简化试验流程详解
2017/09/26 Javascript
JS控制鼠标拒绝点击某一按钮的实例
2017/12/29 Javascript
Vue中使用Sortable的示例代码
2018/04/07 Javascript
详解使用create-react-app快速构建React开发环境
2018/05/16 Javascript
关于vue利用postcss-pxtorem进行移动端适配的问题
2019/11/20 Javascript
详解Vue的ref特性的使用
2020/01/24 Javascript
ES6函数和数组用法实例分析
2020/05/23 Javascript
Python中的特殊语法:filter、map、reduce、lambda介绍
2015/04/14 Python
Python中元组,列表,字典的区别
2017/05/21 Python
MAC中PyCharm设置python3解释器
2017/12/15 Python
基于DataFrame筛选数据与loc的用法详解
2018/05/18 Python
Tensorflow实现卷积神经网络的详细代码
2018/05/24 Python
python3 实现一行输入,空格隔开的示例
2018/11/14 Python
Python虚拟环境的原理及使用详解
2019/07/02 Python
利用Python将图片中扭曲矩形的复原
2020/09/07 Python
基于Pytorch版yolov5的滑块验证码破解思路详解
2021/02/25 Python
校班主任推荐信范文
2013/12/03 职场文书
住宿生擅自离校检讨书
2014/09/22 职场文书
党员“四风”问题批评与自我批评思想汇报
2014/10/06 职场文书
内乡县衙导游词
2015/02/05 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
您对思维方式了解多少?
2019/12/09 职场文书
Ajax是什么?Ajax高级用法之Axios技术
2021/04/21 Javascript
Android RecyclerView实现九宫格效果
2022/06/28 Java/Android