寫爬蟲之前,首先要明確爬取的數據。然后,思考從哪些地方可以獲取這些數據。下面以一個實際案例來說明,怎么尋找一個好的爬蟲策略。(代碼僅供學習交流,切勿用作商業或其他有害行為)
1).方式一:直接爬取網站 目標網址:http://chanyouji.com/ 注意:這個網站會攔截IP,訪問次數過多,IP會被封,所以,上節的IP代理就用到了。
a).打開網頁,可以看到這是一個游記類的網站,里面有很多人分享的游記。那我們就爬這些游記。說不定以后有時間出去玩的時候可以用到。
b).點開其中一篇游記,可以看到鏈接地址形式是這樣的 http://chanyouji.com/trips/352140,這個時候,我們可以思考一下,352140這個數字代表的含義,會不 會是這個游記在數據庫的ID,如果是的話,換個數字會不會得到不一樣的游記,那么我們試一下。訪問 http://chanyouji.com/trips/352141,可以看到,的確得到了不 一樣的游記。截圖如下:
c).從網址上可以得出一個結論,我們可以通過枚舉來請求到不同的數據。但是,這並不一定是可以按照上兩節的方式來爬取。原因有很多。比如,有些數據是通過js渲染 的。對於有web開發基礎的很好理解,但是對於沒有做過web開發的同學解釋一下。假設,我們要買一個房子,房子有很多種,我們分成兩類,一類是毛坯房(就是沒有裝修 的),一類是裝修好的。對於毛坯房,我們要買家具,裝修什么的,對於裝修好的我們可以直接用。類比到這個例子中,http://chanyouji.com/trips/*****這個請求就買 一個房子,毛坯房就是說返回的是這個網站的殼子,需要另外在JS里面重新請求數據,填充到殼子里面。裝修好的就是,數據什么的都填好了,一起給你。
d).那么我們該如何判斷,這兩類的結果呢。很簡單。以火狐瀏覽器為例,F12打開調試窗口,找到網絡->點擊相應的請求,可以看到如下界面:
這個請求的所有的數據都會顯示在這個里面,然后點開響應,會看到請求來的源代碼(這個也是我們用爬蟲發請求的結果),如圖所示
很慶幸,我們獲取到的是精裝房,可以直接利於上兩節的知識來解析這個代碼(這里就不贅述了)
e).如果是js渲染的怎么辦呢?我沒在這個網站上找到用js渲染的(這個網站的數據還是比較好爬,除了攔截IP之外,沒有多少難度),所以換個目標來解釋。
2) 方式二:分析請求 目標網址:http://music.163.com/#/user/home?id=48353(丁磊的網易雲音樂個人主頁)開始分析方法和上一步一樣,頁面截圖如下:
a).我們發現,http://music.163.com/user/home?id=48353 這個請求返回的值是不是少點什么,對的,就是少了歌單(如果多分析幾個用戶的頁面,你會發現,年齡 也是缺的)
b).我們繼續尋找那個歌單的數據在哪里?
可以看到,http://music.163.com/weapi/user/playlist?csrf_token= 這個請求就是返回的歌單,我們只需要請求這個接口的時候,帶上該有的參數,就能得到這個數據。返回的數據是json格式,可以拿過來直接用了,不用beautifulsoup解析。另外說一句,這個接口的參數是加密的,如下圖,網上有破解的,但是不推薦破解,因為只要他們隨便改下密鑰或者加密方式,又要花很大時間來破解。對於這個接口,我們一般參與,分析js(網易雲音樂的js也是混淆過的)或者調用瀏覽器來訪問(這個效率比較低,但是個人來講夠用了)。
3)方式三:另辟蹊徑——利用目標網址的APP。這里仍以 蟬游記 為例。APP的接口返回值一般都是JSON,比較好解析,除了網易雲音樂(丁磊就該好好養豬)。核心就是攔截APP的請求。
a).在電腦上安裝安卓模擬器(我用的是bluestacks,這個安裝好像有點麻煩)
b).在模擬器中安裝目標APP--蟬游記(除了這個方法之外,還可以用電腦開個熱點,用手機連接這個熱點,同樣可以攔截)
c).安裝http analyzer其他的也行,就是攔截http請求用的),打開httpanalyzer
d).使用目標APP,這個時候就可以攔截到想要的請求,如圖:
e).請求就是這樣的,這里要注意,https和http的區別。遇到https的請求,我們先試下用http替換。很慶幸,這個網站可以這樣做,如果不可以的話,比較麻煩,還要導 入證書(暫且不講)。我們把http://chanyouji.com/api/trips/352140.json (為了和方式一同步,把id改成了352140)發到瀏覽器中請求,結果如下(說明請求的時候不 需要加任何參數)
f).這些數據比較多,很難看。怎么看好看一點呢,就是把它轉化成標准的json數據,我一般用這個工具http://www.bejson.com/jsonviewernew/
把數據復制過去格式化一下就行了。如下圖所示:
g).順便說一句,python有json解析模塊,可以用。
下面附上蟬游記的爬蟲源碼(僅供學習交流!僅供學習交流!僅供學習交流!)
import urllib import json import socket socket.setdefaulttimeout(10) proxys = [] proxys.append({"http":"http://124.251.62.246:80"}) proxys.append({"http":"http://117.78.34.32:80"}) proxys.append({"http":"http://59.108.61.132:808"}) for id in range(0,5,1): try: url = "http://chanyouji.com/api/trips/"+`(352140+id)`+".json" res = urllib.urlopen(url,proxies=proxys[id%3]).read() res_json = json.loads(res) print res_json['name'] except Exception,e: print e continue
運行結果:
代碼說明:
a).枚舉可以用循環
b). res_json = json.loads(res) 就是把結果轉化成json,特別注意,這個res必須要有和json格式一樣(json相關資料,可自行查閱)。
c).proxys.append()就是往數組中添加元素
d).id%3 就是id處於3取其余數,也就是說 id%3大於等於0,小於等於2。因為代理只有三個,數組是從零開始。
到此,簡單的爬蟲策略就講完了。
備注:
a).所有內容僅供學習交流使用
b).如有錯誤,多多指教
c).轉載請注明出處