如何「爬數據」?
剛剛看到@走刀口 的一個回答,通過寫程序的手段使用了知乎上的統計數據。請教:這個數據是怎麼「爬下來」的?
更新於 2017 年,Google 已經出了官方的 puppeteer,其他的可以退休了。
補充下匿名用戶的第三點,用基於webkit的工具就ok了,如
- Selenium - Web Browser Automation
- CasperJS, a navigation scripting and testing utility for PhantomJS
- PhantomJS: Headless WebKit with JavaScript API
- segmentio/nightmare
- GoogleChrome/puppeteer
其他簡易的就多的去了:
- httpclient: HttpClient - HttpClient Home
- request.js: https://github.com/mikeal/request
- node.io: https://github.com/chriso/node.io/wiki
- jsdom : tmpvar/jsdom · GitHub
參見我之前的一個答案: 如何在前端自動化測試中模擬用戶的操作?
解析方面,簡單的用正則表達式,複雜的用dom分析(如jquery/html parser等github上一大堆類庫)。
譬如我這段用來分析知乎的收藏夾:https://github.com/unogz/izhihu/blob/develop/src/modules/collection.js#L56PS:最近在參與愛知乎插件,官方沒有API真的很不方便,POST的介面都是直接返回html的,要自己爬數據。
以上。
簡單籠統的說,爬數據搞定以下幾個部分,就可以小打小鬧一下了。
一、指定URL的模式,比如知乎問題的URL為http://zhihu.com/question/xxxx,然後抓取html的內容就可以了。用的工具,如果你正則很好,可以用正則,覺得正則費腦子的,可以用html解析DOM節點來處理內容。如果你抓取的內容有其固有特點,如新聞內容,可以用正文抓取演算法,其實就是找html中最長的幾行字元串。二、用javascript動態生成內容的抓取,不建議使用headless,效率比較低下,建議使用一些開源的庫去直接執行js代碼,獲得你想要的結果。
了解頁面里的程序邏輯是很重要的,知道動態內容是怎麼生成的,使用一定的方法,一樣會像拿html一樣,很容易的拿到你想要的結果。動態生成要麼是本地執行計算,要麼是從伺服器另發起請求獲得一定的結果,顯示或再進行本地計算。對前者,你要找到他本地執行的那段代碼,原樣拿過來,在javascript環境執行一遍拿到結果。對後者,找到那個請求,獲得對應的結果,一般這個結果也會是javascript代碼或者json格式的字元串,重新解析即可。三、登錄,有很多數據你是需要登錄後才能查看的。如果對方使用https,基本就無解了。好在很多國內標榜全站使用https的網站都是偽https,抓包一樣全都可以抓到,比較複雜的會將用戶名或密碼進行二次加密,並且和時間相關,直接提交用戶名密碼是無效的,必須同時提交以當前時間為參數進行二次加密後的結果,還是那句話,了解頁面里的程序邏輯是很重要的。
四、驗證碼,你抓取過多過快時,網站一般會要求你輸入驗證碼證明你不是程序,是人工在操作,似乎國內有幫你輸入驗證碼的雲服務,來搞定這部分,或者用程序解析驗證碼,但錯誤率太高。還有一種比較無賴的方法就是使用多條ADSL或VPN,來回切換IP,不斷換IP進行抓取,把單IP抓取速度控制在網站允許的範圍內,另外什麼換header頭裡的agent啥的比較簡單,就不多說了。
五、內容圖片化,一些敏感信息,如商城裡的價格,分類網站里的用戶手機號,會被網站直接用圖片的方式進行顯示。這裡你使用雲服務成本太高,使用程序解析圖片,如果出錯,這條信息基本就沒用了,切換IP也一樣是圖片,所以基本也是無解的。
六、補充,爬蟲還有很多細節和針對性的處理方法,出於學習的目的,要多思考,比如移動互聯網這麼火熱,很多網站,有點實力的都會出移動客戶端,在移動客戶端內,他還是使用圖片顯示嗎?現在html5出來了,很多移動客戶端都是html+js進行再封裝處理的。
—————————分割線,討論抓取的可持續性——————————
一個網頁的鏈接有n多,也就是說你會遇到一個頁面開始,然後1*n*n*n這種方式展開的鏈接個數,同時鏈接會有重複的,於是如何保存已抓取的鏈接和如何把滿足某些條件的鏈接篩選出來會是你需要解決的一個新問題。好了,當你有一個鏈接處理機制來幫助你管理你抓取的所有鏈接後,你爬蟲的抓取效率變得非常高效,高效到你的爬蟲因此被目標網站屏蔽了,你該如何解決?改header頭的東西我就不多說了,只說關鍵的屏蔽ip怎麼解決?
你需要將你的爬蟲做成分散式,由中央伺服器作為任務調度中心,處理抓取的頁面,將要抓取的鏈接分發到各個轄屬機器。轄屬機器只做一件事,就是向中央伺服器請求任務,並把請求來的任務執行後將結果返回給調度中心。每個轄屬機器是一台幾十塊一年的虛擬機即可,我們要的是轄屬機器的ip而已。好了,現在你由n多個ip分散在n個機器中替你做抓取,數據統一集中在你隱藏在幕後的中央伺服器里,效率非常高,一般你控制的好,目標伺服器不會發現某個ip請求過於頻繁,流量過高,但是事情有可能就是那麼變態!目標伺服器還是發現了你!把你所有的小爬蟲都幹掉了!怎麼辦?
你需要優化調度中心的東西,你的中央伺服器不能只簡單的把任務平均分給各個轄屬機器,你需要實時的監控各個轄屬機器的任務數量與執行狀態,任務過高的轄屬機器得讓他歇歇,免得他被幹掉,這事為啥不在轄屬機器里做呢?因為我們用的是幾十塊一年的虛擬機啊!!成本啊!!你有錢買幾千塊一年的機器當我沒說啊!!
好了,現在你的任務調度中心很智能的保證每個轄屬機器的任務不會過高,如果你嫌效率還是低,再開一個虛擬機就好了。ip也有很多,訪問頻率和流量你也控制的很好,鏈接管理也控制的很好,基本上爬蟲的框架就有個雛形了。你是指蜘蛛程序抓取網頁么?
- 通過分析網頁的地址,用程序遍例出你所需要的地址。
- 通過對網頁HTML標籤的分析,抓取出你所需要的數據。
知乎沒有開放API,所以只能是寫程序爬。就單純的爬網頁相當簡單,只要會解析即可。大致步驟無非就是1.獲取網頁內容——&>2.解析獲得想要的東西。
1.如果伺服器端有防止程序亂來的話,估計要偽造請求頭,主要是User-Agent。一些特殊情況要注意加:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.82.統計數據我不知道是哪裡,但是這個肯定是要登錄了之後才會有。這樣的話,要用到cookies.Python的urllib以及Java的Httpclient都支持的。
3.目前很難解決的就是有些網頁是經過javascript渲染的。高手已經解決@天豬(劉勇) ,用headless webkit 之類的模擬工具, selenium / capserjs / phantomjs。
開放平台API才是王道,爬數據僅在急需某些特殊數據,難以手工搞定的情況下才做。不適合用於生產環境,別人改一點點東西,你也得跟著改。就像和12306對搞的搶票插件一樣,天天守著,比的就是精力。。爬知乎的數據主要麻煩之處在於沒登錄的用戶看到的東西很有限,而知乎的頁面解析實在是太簡單了。
http://dom.jumony.net/87D8D2F0BCB745405DDBB3637461B1D18330E58C?selector=a%5Bdata-votecount%5D比如說這樣就抓下來這個頁面所有答案的票數了。
用什麼包就不說了,太多了。
因為簡歷上缺項目,用python寫過一個跑html的包做了個小搜索引擎。分享一下個人見解。1、為什麼叫「爬數據」?
爬數據的「爬」,取自於英文web crawler。(第一次硬是沒明白為什麼叫這名字,預想可能是剛出現這東西的時候跑得很慢)2、怎麼爬?
簡單的說,想像自己看一個網頁然後右鍵存下來,標記訪問過,再點擊網頁上出現的未訪問過的所有鏈接,再一個個存下來,只要有下一個鏈接,你就繼續點。所謂的爬只是用程序實現了這個過程。總的來說根據目標不同有兩種點法:
這裡引入圖論,比如要「爬」一個網站,我們把整個網站看做一張圖,從主頁到最深層的子頁。圖的遍歷方法有兩種:Depth First Search (深度優先搜索):使用遞歸搜索到最深層的子頁,然後向上搜索,內存佔用較高,可以先目標到此網站的最末端比如說資源下載鏈接,圖片鏈接。
Breath First Search(廣度優先搜索):使用queue(隊列)實現一層層的搜索,內存佔用較低,會優先目標網站的主頁面,副頁面以及一般瀏覽頁面。
第二種用得比較多,用於把網站的幾個主要頁面弄下來以後停止。
當然如果用到很牛逼的設備,還得注意「politeness」(禮貌),像用google的設備用得不好可以幾毫秒擠垮一個網站,這樣就屬於攻擊了,爬的同時不要佔用網站正常客戶的流量。
3、有什麼用?
crawler最大的用處就是搜索引擎了,比如google的crawler會遍歷各種各樣的網站然後作為文件存儲下來,當用戶發出搜索命令時,只需在伺服器搜索里給出結果。可以說沒有crawler,就沒有搜索引擎。當然,現在所謂的大數據,很多也就是把這些存下的頁面做字詞分析,現在這麼火主要在於數學分析模型的進步。而弄到數據的方法,早就不是什麼新鮮的東西。
4、用什麼語言?語言上並沒有太多限制,在受歡迎程度上看,python在這一領域有絕對優勢。http://mota.baidu.com 這個網站的APP數據是不用爬就有的啊
免費申請,可以參考。
百度MOTA是專業的移動數據分析平台,專註於移動應用及其設備和人群的數據監測、挖掘、分析和可視化展現。百度 MOTA可以幫助用戶了解移動行業及各細分領域發展趨勢, 分析移動應用運營現狀,把握用戶特徵屬性和行為偏好,為產品優化和運營推廣效果提升、投資分析、移動市場分析等提供參考。
百度MOTA依託於百度海量的用戶積累以及強大的技術能力,通過收集用戶授權數據並進行匿名化和模糊化處理,構建計算和分析模型,進行數據挖掘,進而估算出移動市場和應用數據。百度MOTA將不斷進行數據補充和產品優化,為用戶提供更加精準、全面、獨特的數據服務。
之前做過相關工作,利用JAVA去實現。原理很簡單,獲得主目錄,然後一級一級往下走。走到最底層的時候,提取自己想要的內容,存入資料庫。當然這其中設計很多細節問題,需要用懂正則表達式,對網站結構的研究等等。
寫過一個爬各大漫畫網站的漫畫的軟體IFComicDownloader,用Lua保存每個站點的解析邏輯,用libcurl做HTTP通信,用sqlite保存下載記錄,跟網際快車差不多。基本上就是對於一個初始頁面,分析頁面里的每一個鏈接,根據鏈接的位置推測目標URL的頁面類型,決定是否要進一步深入遞歸。然後根據網頁類型和網頁之間的鏈接關係,將數據和數據之間的關係保存到本地。
如果是爬微博等主流網站的數據,應該會比較簡單一些。
比如最近同學有跟我推薦gooseeker 集搜客網路爬蟲 。
百度一下就可以查到,有免費版,打包數據會收取一定費用,但價格也還好。
此外還有八爪魚之類的軟體,或者Python裡面也有相關的包。
目前是用httpclent分享:http://blog.csdn.net/biexf/article/details/6029739如何對付網路爬蟲 - JavaEye和網路爬蟲鬥爭之路
Python 做爬蟲 入門很快 谷歌一下就知道了
一般流程首先使用抓包工具獲取數據包並分析出請求邏輯,試了很多工具,還是httpfox最好用。然後分析網頁源碼獲取數據,使用正則表達式來的最舒服,也可以使用很多第三方庫。這方面Python算是很有優勢了,本身語言不難學,實用庫也不少,很適合學著以後自己做一些小工具。一般靜態網頁十行左右代碼就差不多。變態一些的數據是靠JavaScript動態生成,這時可以模擬瀏覽器行為。這樣就能滿足普通需求了。再深入一些就是對戰環節了………
使用火車頭數據採集軟體,簡單方便
如果用java的話,可以試試Jsoup
通常大型抓取項目都會選擇Apache Nutch,Nutch從2005年到今天已經發展了十年,先後孕育出來Hadoop,Hbase,Gora,Lucene,Solr等關聯項目。最簡單的爬蟲,只需要幾十行代碼,譬如:
How do I make a simple crawler in PHP?
那麼為什麼Nutch有那麼龐大?
主要原因包括:
1. 分散式抓取,支持數百台機器同時工作
2. 大規模抓取,支持TB,PB級別網頁
3. 複雜控制,數百個配置參數
4. 多種網路協議支持,HTTP,HTTPS,FTP,SFTP等等
5. 多種內容解析,除了html外,還支持pdf,doc等解析
6. 性能,Nutch最高可以支持單台機器一天抓幾億網頁
但為什麼還是有那麼多人願意自己寫爬蟲?除了Nutch學習曲線相當陡峭外,還有以下原因:
1. 不支持眾包抓取或者代理資源池
2. 不支持Ajax
3. 不支持登錄抓取
4. 不支持擬人行為
5. 不支持深網數據和暗網數據抓取
6. 不支持簡單的網頁抽取
7. 不支持「小白級」管理界面
要解決這些問題,需要對Nutch進行改造。涉及Nutch源代碼技術細節的部分,略去不表,說說擬人行為和網頁抽取。
擬人行為的實現。需要一個真正的網頁瀏覽器,要程序去操作這個瀏覽器來訪問目標網頁,載入css,渲染頁面,執行javascript,必要時需要執行頁面滾動、滑鼠懸浮等操作,為的是完全載入目標頁面。譬如絕大多數電商網站,其中的圖片都是延遲載入的,頁面滾到哪裡,那裡的圖片才開始載入。這時候就需要在網頁中執行頁面滾動操作。具體工具有phantomjs等。
網頁抽取的實現。最簡單的網頁抽取,就是根據網頁中目標數據項的css path來提取。這種方法太過簡單,有很多問題:1. 人工維護成本巨大 2. 目標網站一旦發生修改,抽取規則就需要全部修改 3. 複雜網頁中css path不能準確抽取目標數據。
htmlunit+jsoup
不用自己爬,有地方賣數據的。比如下面的產品數說聚合
推薦閱讀:
※0點48分』誰還在知乎
※怎麼評價知乎反作弊系統?
※如何看待「知乎大神」原來是留幾手的賬號?
※Citations:關於知乎的現狀