使用python,scrapy寫(定製)爬蟲的經驗,資料,雜。

近期找工做略不順。技術無用。晚上寫下了這點東西。css

首先說下最近在找工做的x的大概相關技術加點路線。py 3年+,linux平常熟練,限於不擅web、手機app開發,一直無太好的可展現的東西。前段時間從一家小公司離職。年前投下,沒啥的話,年後再看下。先投的py爬蟲的,沒合適的再看運維和py相關其餘。java

正文開始前略吐槽下,我以前工做的小公司,在我去以前,仍是多線程urllib爬正則解析,網頁編碼解析從GBK,UTF8依次猜。他有點強讓我走了。node




我開始大量使用scrapy時,scrapy已經是0.16版。這個版本相對比較成熟,該版本持續了近一年時間,13年夏發佈0.18版。在網上搜scrapy資料,中文的相對較少,爲數很少的幾篇也多寫於scrapy較早的版本(提醒看資料注意發佈時間)。從舊資料看,早期的scrapy,尚未dns解析緩存,url去重等功能。到0.16時,scrapy已基本成型,差的幾個功能(如HTTP長鏈接,仿瀏覽器緩存機制(RFCXXXX)的CACHE)陸續在0.18,0.20裏面上實現了。Scrapinghub(寫scrapy的人搞得公司)上的產品也更豐富了。python

scrapy的優勢在於成熟完善,定製開發快。linux

scrapy對比其餘我所知的定製爬蟲解決方案。主要對比python內的幾個方案。git

JAVA:nutch,hetrix...etc。這幾個更適合作通用爬蟲或少許的定製爬蟲,相對scrapy優勢是資料比較多,成熟。不過用java系的寫大量定製爬蟲應該比較痛苦。github

Ruby:不瞭解,僅據說ruby有個爬蟲庫。web

Node.js:遇到有個初創團隊用node.js寫的,負責人有scrapy(<0.16),gevent經驗。不瞭解。面試

python:gevent及其餘py的爬蟲框架。稍後會詳細描述這部分。redis


對於gevent上寫爬蟲的各位,我只能說大家有實力,大家爲什麼要造輪子,大家確定有本身的理由的,推薦參考下scrapy造輪子。gevent寫爬蟲大概的方案是gevent+requests+一個隊列庫(redis,beanstalk.etc.)。須要注意的點和坑有以下一些。

0,gevent使用協程,monkey_patch後一些調試方法不可用。

1,requests的編碼檢測是不符標準的,他有兩個編碼,一個是http head裏面的編碼,另外一個是依據網頁body的編碼。標準是網頁內容聲明的編碼優先於http頭的編碼,requests沒有作這個考慮,老是使用head裏面的編碼。在head和body編碼聲明不一致時可能出現編碼錯誤。

2,gevent的同步機制略少,某些狀況下協程同步效率低。這個是我在寫http代理調度器(相似Crawlera)的東西時遇到的。http代理調度器我下面會說起。

3,其餘各類細節。太多。如requests開gzip,requests鏈接池等等。太多太多。

gevent相對於scrapy的優勢有:

1,若是涉及到底層定製 ,gevent比scrapy所用的twisted簡單。我曾想給scrapy嵌一個http代理調度功能,發現略難,須要很瞭解twisted。

2,若是你只須要不多的幾個簡單爬蟲,你可能以爲gevent用着更順手(但scrapy也很容易)。對於純下載網頁,用gevent實現比scrapy快,畢竟scrapy還有其餘功能,但這有個前提,你有很高很高的帶寬,要先達到scrapy的下載頁面速率上限。


python還有其餘幾個爬蟲框架,我都大體看過源碼。有個框架有個讓你人工輸驗證碼的demo(名字忘了)。其餘沒什麼特別的了。

scrapy經驗,資料

資料:官方文檔,http權威指南,一些博文。

看文檔時仔細點,不少功能都有。

scrapy github帳號的各種repo(https://github.com/scrapinghub)有不少好東西,如:

1,scrapyjs,splash:爬蟲遇到的js問題的解決方法(JS解析會在下面說起)

2,webstruct...etc:機器學習,模糊匹配等用來解析網頁內容的。

3,etc...

scrapy有個SEP相似PEP的,能夠一看,也在github的倉庫。

留意scrapy的博客http://blog.scrapinghub.com/

wiki:https://github.com/scrapy/scrapy/wiki

scrapy公司(http://scrapinghub.com/)的產品:

1,定製爬蟲(讓scrapy公司幫你寫爬蟲而後交付你)

2,scrapy cloud(提供跑爬蟲的服務器(scrapyd))

3,autoscraping(點擊須要內容便可實現爬取)

4,crawlera,解決爬網站的ip限制問題(我有一個相似功能的本地版http代理調度器及大量代理)。


一些常見問題,經驗:

0,瞭解scrapy已經作過的功能,優化等。。。防止重複造輪子,如,去重,編碼檢測,dns緩存,http長鏈接,gzip等等。

1,JS相關。

這個是被問的最多的。看具體狀況解決。可模擬相關js執行、繞過,或直接調瀏覽器去訪問。本身用一個JS引擎+模擬一個瀏覽器環境難度太大了(參見V8的DEMO)。

調瀏覽器有不少方法。難以細說,關鍵字以下,selenium,phantomjs,casperjs,ghost,webkit,scrapyjs,splash。一些細節如關掉CSS渲染,圖片加載等。只有scrapyjs是徹底異步的,相對是速度最快的,scrapyjs將webkit的事件循環和twisted的事件循環合在一塊兒了。其餘的方案要麼阻塞,要麼用多進程。簡單的js需求(對效率要求不高)隨意選,最優方案是scrapyjs+定製webkit(去掉不須要的功能)。調瀏覽器開頁面是比較耗資源的(主要是cpu)

2,內容解析。

XPATH就能夠了,感興趣能夠看下pyquery,css選擇器。

若是想得到網頁對應的txt,能夠調瀏覽器,有個相似plain_txt的接口能夠獲取網頁保存成txt。

模糊匹配參考scrapy github裏面幾個庫,機器學習不必定好用(效果問題,人工問題-須要訓練)。還有寫些正則去模糊匹配。

新聞相似的正文提取有readability,boilerplate。

3,分佈式。

首先考慮按任務(目標)切分,而後讓不一樣目標的爬蟲在不一樣機器上跑

徹底的對等分佈式(多爬蟲爬一個目標),把任務隊列替換掉爬蟲改改便可。github裏面有幾個現有的實現參考。

分佈式需求多是僞命題。想清楚爲什麼要分佈式。硬件夠不夠,像什麼拿一個不支持持久化的url隊列的爬蟲說量大須要分佈式的,我只能默唸,你爲什麼這麼吊。

4,部署,調度

部署推薦scrapyd。這也是官方推薦的方法。

大量爬蟲的調度,這個目前(13-10)沒有現成的合適方法,指望是實現爬蟲的某些配置放數據庫,提供web後臺 ,而後按配置週期、定時運行爬蟲,終止,暫停爬蟲等等。能夠實現,但要本身寫很多東西。

5,ip限制問題

買的起大量ip的可買(買大量同網段爬可能致使整網段被封)。

找大量免費的開放http代理,篩選可用的,免費開放代理不可靠,寫個調度機制,自動根據成功次數,延遲等選擇合適代理,這個功能難以在scrapy內實現,參考scrapinghub的crawlera,我完成了一個本地版。

6,url去重。

若是有千萬級的URL須要去重,須要仔細看下scrapy的去重機制和bloom filter(布隆過濾器)。bloomfilter有個公式能夠算須要多少內存。另bloomfilter  + scrapy在github有現有實現能夠參考。

7,存儲。

mongodb,mongodb不知足某些功能時考慮hbase,參考http://blog.scrapinghub.com/2013/05/13/mongo-bad-for-scraped-data/

8,硬件扛不住別玩爬蟲。。。曾在I3 4G 1T上跑爬蟲。卡在磁盤io(量大,磁盤io差,內存低),出現內存佔用飆升。很難調試(調試爬蟲看實際跑耗時較長),初步覺得是爬蟲有問題內存佔用高致使數據庫卡。調試結果確認爲,配置低量太大,致使數據庫慢,數據庫慢以後爬蟲任務隊列佔滿內存並開始寫磁盤,又循環致使數據庫慢。

9,爬蟲監控

scrapyd自帶簡單的監控,不夠的話用scrapy的webservice本身寫,暫無(13.10)現成的

9,=。=想到再補充。





最後說個故事。

面試的時候注意點到爲止。幾個雕坐在一個地方問了ban一下午的爬蟲相關各類問題、方案、細節,還準備讓我寫個DEMO,加來回快一天了。

相關文章
相關標籤/搜索