python 爬蟲如何正確的使用cookie
很多時(shí)候,我們要查看的內(nèi)容必須要先登錄才能找到,比如知乎的回答,QQ空間的好友列表、微博上關(guān)注的人和粉絲等。要使用爬蟲直接登錄抓取這些信息時(shí),有一個不太好解決的難題,就是這些網(wǎng)站設(shè)置的登錄規(guī)則以及登錄時(shí)的驗(yàn)證碼識別。不過,我們可以想辦法繞過去,思路是這樣的:先使用瀏覽器登錄,從瀏覽器獲取登錄后的“憑證”,然后將這個“憑證”放到爬蟲里,模擬用戶的行為繼續(xù)抓取。這里,我們要獲取的憑證就是cookie信息。
這次我們嘗試使用python和cookie來抓取QQ空間上的好友列表。使用的工具是FireFox瀏覽器、FireBug和Python。
獲取cookie
打開FireFox瀏覽器,登錄QQ空間,啟動FireBug,選擇FireBug中的Cookies頁簽,點(diǎn)擊頁簽中的cookies按鈕菜單,選擇“導(dǎo)出本站點(diǎn)的cookie”即可完成cookie的導(dǎo)出。

導(dǎo)出cookie會以一個名為cookies.txt文本文件形式存在。
程序?qū)崿F(xiàn)
然后我們會使用獲取的cookie新建一個opener來替換之前請求時(shí)使用的默認(rèn)的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 rel="external nofollow" >http://user.qzone.qq.com/QQ號/myhome/friends</a>)
因?yàn)槲覀兪褂玫氖荈ireFox瀏覽器導(dǎo)出的cookie文件,所以這里使用的cookieJar是MozillaCookieJar。
執(zhí)行腳本…然而報(bào)錯了:
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文件開始一行添加如下內(nèi)容即可:
# Netscape HTTP Cookie File
通過這行內(nèi)容提示python cookie解析器這是一個FireFox瀏覽器適用的cookie。
再次執(zhí)行,還是會報(bào)錯,因?yàn)楸容^長我就只貼關(guān)鍵的部分出來:
http.cookiejar.LoadError: invalid Netscape format cookies file 'cookies.txt': '.qzone.qq.com\tTRUE\t/\tFALSE\tblabla\tdynamic'
意思是cookie中某些行存在格式錯誤。具體錯在哪兒,需要先了解下FireFox瀏覽器的cookie格式。MozillaCookieJar認(rèn)為每行cookie需要包含以下信息,每條信息以制表符分隔:
| 名稱 | domain | domain_specified | path | secure | expires | name | value |
| 類型 | 字符串 | 布爾型 | 字符串 | 布爾型 | 長整型 | 字符串 | 字符串 |
| 說明 | 域名 | — | 適用路徑 | 是否使用安全協(xié)議 | 過期時(shí)間 | 名稱 | 值 |
其中domain_specified是什么意思我不很清楚,以后弄明白了再補(bǔ)上。再來看看我們獲取的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”屬性。該怎么辦呢——補(bǔ)上就好了唄。在其他的cookie中隨意選一個時(shí)間補(bǔ)上就OK了。
補(bǔ)全cookie后,再次執(zhí)行是正常的,沒有報(bào)錯。但是沒有如預(yù)期的打印出好友信息,因?yàn)榫W(wǎng)址錯了。使用firebug可以找出正確的網(wǎng)址:
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字符串。

至于如何解析json,會在下一節(jié)進(jìn)行說明。
動態(tài)獲取cookie
cookie是有過期時(shí)間的。如果想長時(shí)間抓取網(wǎng)頁,就需要每隔一段時(shí)間就更新一次cookie。如果都是從FireFox瀏覽器來手動獲取顯得有些笨了。從瀏覽器獲取的cookie只是作為一個入口,之后再進(jìn)行請求還是要依靠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兩項(xiàng)屬性。通過實(shí)例可以看到每次執(zhí)行http請求都會重新獲取cookie,因此可以將我們的程序調(diào)整一下:執(zhí)行第一次請求時(shí)使用我們通過瀏覽器獲取的cookie,之后的每次請求都可以使用上次請求時(shí)獲取的cookie。調(diào)整后的程序:
#!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)
就這樣。
其他
其實(shí)在登錄QQ空間時(shí)使用cookie還有另一種法子——通過觀察,也可以在http 請求頭中添加cookie信息。
獲取請求頭中cookie的方式:打開FireFox瀏覽器,打開FireBug并激活FireBug的network頁簽,在FireFox瀏覽器上登錄QQ空間,然后在FireBug中找到登錄頁請求,然后就可以找到請求頭中的cookie信息了。

將cookie信息整理成一行,添加到請求頭中就可以直接訪問了。這個方法相對簡單,減少了修改cookie文件的步驟。
此外,在一篇博客文章中還找到了直接登錄QQ空間的方案。這算是已知最好的法子了,只要騰訊不改變登錄規(guī)則就能很簡單的執(zhí)行請求獲取cookie。不過年代久遠(yuǎn),不知規(guī)則是否還適用
以上就是python 爬蟲如何正確的使用cookie的詳細(xì)內(nèi)容,更多關(guān)于python 爬蟲使用cookie的資料請關(guān)注腳本之家其它相關(guān)文章!
- Python3爬蟲帶上cookie的實(shí)例代碼
- Python爬蟲使用瀏覽器cookies:browsercookie過程解析
- Python3爬蟲之urllib攜帶cookie爬取網(wǎng)頁的方法
- python爬蟲中g(shù)et和post方法介紹以及cookie作用
- python爬蟲使用cookie登錄詳解
- Python爬蟲番外篇之Cookie和Session詳解
- Python爬蟲利用cookie實(shí)現(xiàn)模擬登陸實(shí)例詳解
- 玩轉(zhuǎn)python爬蟲之cookie使用方法
- Python中urllib+urllib2+cookielib模塊編寫爬蟲實(shí)戰(zhàn)
- python爬蟲中PhantomJS加載頁面的實(shí)例方法
- Python爬蟲JSON及JSONPath運(yùn)行原理詳解
- Python爬蟲如何破解JS加密的Cookie
相關(guān)文章
python如何實(shí)現(xiàn)常用的五種排序算法詳解
排序有很多種實(shí)現(xiàn)方法,比如冒泡排序、選擇排序、歸并排序、希爾排序、快速排序、插入排序、堆排序、基數(shù)排序等,這篇文章主要給大家介紹了關(guān)于python如何實(shí)現(xiàn)常用的五種排序算法,需要的朋友可以參考下2021-08-08
Python定時(shí)任務(wù)sched模塊用法示例
這篇文章主要介紹了Python定時(shí)任務(wù)sched模塊用法,結(jié)合實(shí)例形式分析了定時(shí)任務(wù)sched模塊的基本功能、參數(shù)含義、多線程定時(shí)任務(wù)等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07
淺析Python 簡單工廠模式和工廠方法模式的優(yōu)缺點(diǎn)
這篇文章主要介紹了Python 工廠模式的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07

