很多时候,我们要查看的内容必须要先登录才能找到,比如知乎的回答,QQ空间的好友列表、微博上关注的人和粉丝等。要使用爬虫直接登录抓取这些信息时,有一个不太好解决的难题,就是这些网站设置的登录规则以及登录时的验证码识别。不过,我们可以想办法绕过去,思路是这样的:先使用浏览器登录,从浏览器获取登录后的“凭证”,然后将这个“凭证”放到爬虫里,模拟用户的行为继续抓取。这里,我们要获取的凭证就是cookie信息。
这次我们尝试使用python和cookie来抓取QQ空间上的好友列表。使用的工具是FireFox浏览器、FireBug和Python。
获取cookie
打开FireFox浏览器,登录QQ空间,启动FireBug,选择FireBug中的Cookies页签,点击页签中的cookies按钮菜单,选择“导出本站点的cookie”即可完成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"text-align: center">至于如何解析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" start(u1, u2)就这样。
其他
其实在登录QQ空间时使用cookie还有另一种法子——通过观察,也可以在http 请求头中添加cookie信息。
获取请求头中cookie的方式:打开FireFox浏览器,打开FireBug并激活FireBug的network页签,在FireFox浏览器上登录QQ空间,然后在FireBug中找到登录页请求,然后就可以找到请求头中的cookie信息了。
将cookie信息整理成一行,添加到请求头中就可以直接访问了。这个方法相对简单,减少了修改cookie文件的步骤。
此外,在一篇博客文章中还找到了直接登录QQ空间的方案。这算是已知最好的法子了,只要腾讯不改变登录规则就能很简单的执行请求获取cookie。不过年代久远,不知规则是否还适用
以上就是python 爬虫如何正确的使用cookie的详细内容,更多关于python 爬虫使用cookie的资料请关注其它相关文章!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]