1. 程式人生 > 程式設計 >python 爬蟲如何正確的使用cookie

python 爬蟲如何正確的使用cookie

很多時候,我們要檢視的內容必須要先登入才能找到,比如知乎的回答,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_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,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_expires=True)
return cookie


def grab(cookie,url):
req = Request(url,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的資料請關注我們其它相關文章!