Python抓取需要cookie的網頁
在仿照《Python小練習:可視化人人好友關系》一文時,需要登錄模擬登錄人人網。然而自從CSDN事件之后,人人網開始使用加密方式處理登錄名和密碼,直接使用post方式已經無法登陸人人網。這時,從豆瓣討論中找到了解決方法:
1. 首先使用瀏覽器登陸人人,然后找到瀏覽器中關於登陸的Cookie;
2. 將Cookie記錄下來,在Python中使用cookie模塊模擬瀏覽器的行為;
3. 取得並解析數據。
1. HTTP協議與Cookie
抓取網頁的過程跟瀏覽器瀏覽網頁的過程是一樣的,了解瀏覽器的工作原理就進行網頁抓取的第一步。
了解HTTP協議和Cookie的有一系列非常好的文章:
* HTTP協議詳解
* HTTP協議 (二) 基本認證
* HTTP協議 (七) Cookie
想要使用Python模擬瀏覽器的登陸,需要使用它自帶的兩個模塊urllib2和cookie,了解urllib2和cookie的使用可以參考:
* HOWTO Fetch Internet Resources Using urllib2
* cookielib and ClientCookie:Handling Cookies in Python
* Dive Into Python:Chapter 11
2. urllib2與cookie使用分析
2.1. 最簡單用法
1 import urllib2 2 page = urllib2.urlopen("http://www.baidu.com") 3 page_data = page.read() 4 print page_data
它直接模擬了登陸百度首頁的方法,打印出來的話你可以看到page_data的內容和瀏覽器里查看到的網頁源碼是一樣的。
2.2. 設置Request信息
有些網頁不希望被抓取,這些網頁所在的服務器可以通過Request的Header信息識別你使用的哪種瀏覽器訪問的。比如大家在論壇常見的這樣的圖片就是這一種原理。
因此我們需要手修改Request的信息,urllib2提供了這一功能。
例:未更改Request
1 import urllib2 2 request = urllib2.Request("http://www.baidu.com") 3 opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1))#為了開啟回顯,需要手動構造一個HTTPHandler 4 feeddata = opener.open(request).read()
可以得到回顯:
1 send:'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: www.baidu.com\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n' 2 reply:'HTTP/1.1 200 OK\r\n' 3 header:Date:Tue,25Mar201411:02:30 GMT 4 header:Content-Type: text/html 5 header:Transfer-Encoding: chunked 6 header:Connection:Close 7 header:Vary:Accept-Encoding 8 header:Set-Cookie: BAIDUID=A12BBEA0BBB616F70334E89B4BB19228:FG=1; expires=Thu,31-Dec-3723:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com 9 header:Set-Cookie: BDSVRTM=0; path=/ 10 header:Set-Cookie: H_PS_PSSID=5610_5631_1428_5224_5723_4261_5567_4759; path=/; domain=.baidu.com 11 header: P3P: CP=" OTI DSP COR IVA OUR IND COM " 12 header:Expires:Tue,25Mar201411:02:20 GMT 13 header:Cache-Control: private 14 header:Server: BWS/1.1 15 header: BDPAGETYPE:1 16 header: BDQID:0xcd6b513700008d44 17 header: BDUSERID:0
其中 send: 'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: www.baidu.com\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n 就是urllib2庫發送的Request Header。服務器可以通過User-Agent
分辨出是哪種瀏覽器瀏覽的網頁。
例:手工設置Request Header:
1 import urllib2 2 request = urllib2.Request("http://www.baidu.com") 3 opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1))#為了開啟回顯,需要手動構造一個HTTPHandler 4 user_agent ="Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 BIDUBrowser/6.x Safari/537.31" 5 request.add_header("User-Agent", user_agent) 6 feeddata = opener.open(request).read()
得到的回顯' send: 'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: www.baidu.com\r\nConnection: close\r\nUser-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 BIDUBrowser/6.x Safari/537.31\r\n\r\n 此時服務器會認為我們在使用其它的瀏覽器瀏覽網頁。
2.3. 使用cookie
使用瀏覽器登陸一個以前已經登陸過的網頁,往往不再需要輸入用戶名和密碼再次登陸,這顆因為瀏覽器已經保存了網站發送來的cookie。下次登陸時,瀏覽器會自動發送相關cookie到服務器,確定目前登陸狀態。因此如果能夠取得一個網站的cookie,就可以不輸入用戶名和密碼模擬登陸這個網站。
Python需要使用cookielib處理cookie。
在登陸一個網頁之后,可以使用Firebug或Chrome的“開發人員工具”查看網頁的cookie。
1 import urllib2 2 import cookielib 3 request = urllib2.Request("http://www.renren.com") 4 cookie = cookielib.CookieJar() 5 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) 6 opener.handle_open["http"][0].set_http_debuglevel(1)#設定開啟回顯 7 user_agent ="Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 BIDUBrowser/6.x Safari/537.31" 8 request.add_header("User-Agent", user_agent) 9 cookie ="t=*************************"#設定cookie的內容 10 request.add_header("Cookie", cookie) 11 feeddata = opener.open(request).read()
此時就可以模擬登陸人人網。