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实现方法
Nov 18 Python
python动态性强类型用法实例
May 09 Python
在Python中操作字符串之rstrip()方法的使用
May 19 Python
Python通过select实现异步IO的方法
Jun 04 Python
python3中set(集合)的语法总结分享
Mar 24 Python
使用python的pandas为你的股票绘制趋势图
Jun 26 Python
Python实现最常见加密方式详解
Jul 13 Python
python通用读取vcf文件的类(复制粘贴即可用)
Feb 29 Python
pycharm工具连接mysql数据库失败问题
Apr 01 Python
Python 连接 MySQL 的几种方法
Sep 09 Python
python制作一个简单的gui 数据库查询界面
Nov 19 Python
深入理解Python变量的数据类型和存储
Feb 01 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代码
2007/03/03 PHP
抓取YAHOO股票报价的类
2009/05/15 PHP
PHP数组交集的优化代码分析
2011/03/06 PHP
PHP gbk环境下json_dencode传送来的汉字
2012/11/13 PHP
七款最流行的PHP本地服务器分享
2013/02/19 PHP
PHP随机生成随机个数的字母组合示例
2014/01/14 PHP
php实现的Timer页面运行时间监测类
2014/09/24 PHP
thinkphp获取栏目和文章当前位置的方法
2014/10/29 PHP
学习php设计模式 php实现合成模式(composite)
2015/12/08 PHP
针对多用户实现头像上传功能PHP代码 适用于登陆页面制作
2016/08/17 PHP
PHP实现的数独求解问题示例
2017/04/18 PHP
php简单处理XML数据的方法示例
2017/05/19 PHP
jQuery.getScript加载同域JS的代码
2012/02/13 Javascript
JavaScript+canvas实现七色板效果实例
2016/02/18 Javascript
jqGrid用法汇总(全经典)
2016/06/28 Javascript
使用jQuery Ajax 请求webservice来实现更简练的Ajax
2016/08/04 Javascript
angular实现图片懒加载实例代码
2017/06/08 Javascript
使用mint-ui开发项目的一些心得(分享)
2017/09/07 Javascript
详解Vue取消eslint语法限制
2018/08/04 Javascript
说说如何使用Vuex进行状态管理(小结)
2019/04/14 Javascript
vue data引入本地图片的两种方式小结
2019/11/13 Javascript
Python列表list操作符实例分析【标准类型操作符、切片、连接字符、列表解析、重复操作等】
2017/07/24 Python
JS设计模式之责任链模式实例详解
2018/02/03 Python
Python3 中把txt数据文件读入到矩阵中的方法
2018/04/27 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
不到40行代码用Python实现一个简单的推荐系统
2019/05/10 Python
python+opencv3生成一个自定义纯色图教程
2020/02/19 Python
纯css3实现图片翻牌特效
2015/03/10 HTML / CSS
HTML5 本地存储实现购物车功能
2017/09/07 HTML / CSS
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
英国的潮牌鞋履服饰商店:size?
2019/03/26 全球购物
预备党员党支部意见
2015/06/02 职场文书
2019行政前台转正申请书范文3篇
2019/08/15 职场文书
浅析Python中的套接字编程
2021/06/22 Python
python 判断文件或文件夹是否存在
2022/03/18 Python
JS setTimeout与setInterval的区别
2022/04/20 Javascript