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获取指定时间差的时间实例详解
Apr 11 Python
python自动登录12306并自动点击验证码完成登录的实现源代码
Apr 25 Python
python+selenium实现自动抢票功能实例代码
Nov 23 Python
python字符串替换第一个字符串的方法
Jun 26 Python
python卸载后再次安装遇到的问题解决
Jul 10 Python
pandas的相关系数与协方差实例
Dec 27 Python
Python 实现opencv所使用的图片格式与 base64 转换
Jan 09 Python
Python实现链表反转的方法分析【迭代法与递归法】
Feb 22 Python
python3 googletrans超时报错问题及翻译工具优化方案 附源码
Dec 23 Python
在vscode中启动conda虚拟环境的思路详解
Dec 25 Python
Django一小时写出账号密码管理系统
Apr 29 Python
整理Python中常用的conda命令操作
Jun 15 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
如何实现给定日期的若干天以后的日期
2006/10/09 PHP
PHP实例分享判断客户端是否使用代理服务器及其匿名级别
2014/06/04 PHP
CentOS下PHP7的编译安装及MySQL的支持和一些常见问题的解决办法
2015/12/17 PHP
php 如何禁用eval() 函数实例详解
2016/12/01 PHP
使用PHP开发留言板功能
2019/11/19 PHP
游戏人文件夹程序 ver 4.03
2006/07/14 Javascript
JavaScript中prototype为对象添加属性的误区介绍
2013/10/15 Javascript
使用struts2+Ajax+jquery验证用户名是否已被注册
2016/03/22 Javascript
JS中的进制转换以及作用
2016/06/26 Javascript
JavaScript实现in-place思想的快速排序方法
2016/08/07 Javascript
JavaScript实现计算圆周率到小数点后100位的方法示例
2018/05/08 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
2018/05/22 Javascript
JS+H5 Canvas实现时钟效果
2018/07/20 Javascript
了解javascript中变量及函数的提升
2019/05/27 Javascript
vue 手机物理监听键+退出提示代码
2020/09/09 Javascript
jQuery插件实现图片轮播效果
2020/10/19 jQuery
[01:54]TI4西雅图DOTA2选手欢迎晚宴 现场报道
2014/07/08 DOTA
[02:28]DOTA2亚洲邀请赛 LGD战队巡礼
2015/02/03 DOTA
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
Python中字典的基本知识初步介绍
2015/05/21 Python
python暴力解压rar加密文件过程详解
2019/07/05 Python
Python 使用SFTP和FTP实现对服务器的文件下载功能
2020/12/17 Python
怎样在程序里获得一个空指针
2015/01/24 面试题
应届生服装设计自我评价
2013/09/20 职场文书
求职简历中自我评价
2014/01/28 职场文书
优秀学生干部推荐材料
2014/02/03 职场文书
专家推荐信模板
2014/05/09 职场文书
公司投资建议书
2014/05/16 职场文书
营销团队口号
2014/06/06 职场文书
幼儿园保育员责任书
2014/07/22 职场文书
雨花台导游词
2015/02/06 职场文书
公司慰问信范文
2015/03/23 职场文书
2016年万圣节家长开放日活动总结
2016/04/05 职场文书
《学会生存》读后感3篇
2019/12/09 职场文书
vue项目多环境配置(.env)的实现
2021/07/21 Vue.js
TV动画《政宗君的复仇》第二季制作决定PV公布
2022/04/02 日漫