~ 寫(xiě)在正文之前:文章轉(zhuǎn)移到翻這個(gè)墻中并思,希望繼續(xù)關(guān)注啦庐氮。(2017.11.5)
本文轉(zhuǎn)載自:http://my.oschina.net/u/1024140/blog/188154?fromerr=AEvPN6XJ
近期找工作略不順。技術(shù)無(wú)用宋彼。晚上寫(xiě)下了這點(diǎn)東西弄砍。
首先說(shuō)下最近在找工作的x的大概相關(guān)技術(shù)加點(diǎn)路線颅筋。py 3年+,linux日常熟練输枯,限于不擅web、手機(jī)app開(kāi)發(fā)占贫,一直無(wú)太好的可展示的東西桃熄。前段時(shí)間從一家小公司離職。年前投下型奥,沒(méi)啥的話瞳收,年后再看下。先投的py爬蟲(chóng)的厢汹,沒(méi)合適的再看運(yùn)維和py相關(guān)其他螟深。
正文開(kāi)始前略吐槽下,我之前工作的小公司烫葬,在我去之前界弧,還是多線程urllib爬正則解析,網(wǎng)頁(yè)編碼解析從GBK搭综,UTF8依次猜垢箕。他有點(diǎn)強(qiáng)讓我走了。
我開(kāi)始大量使用scrapy時(shí)兑巾,scrapy已是0.16版条获。這個(gè)版本相對(duì)比較成熟,該版本持續(xù)了近一年時(shí)間蒋歌,13年夏發(fā)布0.18版帅掘。在網(wǎng)上搜scrapy資料,中文的相對(duì)較少堂油,為數(shù)不多的幾篇也多寫(xiě)于scrapy較早的版本(提醒看資料注意發(fā)布時(shí)間)修档。從舊資料看,早期的scrapy称诗,還沒(méi)有dns解析緩存萍悴,url去重等功能。到0.16時(shí)寓免,scrapy已基本成型癣诱,差的幾個(gè)功能(如HTTP長(zhǎng)連接,仿瀏覽器緩存機(jī)制(RFCXXXX)的CACHE)陸續(xù)在0.18袜香,0.20里面上實(shí)現(xiàn)了撕予。Scrapinghub(寫(xiě)scrapy的人搞得公司)上的產(chǎn)品也更豐富了。
scrapy的優(yōu)點(diǎn)在于成熟完善蜈首,定制開(kāi)發(fā)快实抡。
scrapy對(duì)比其他我所知的定制爬蟲(chóng)解決方案欠母。主要對(duì)比python內(nèi)的幾個(gè)方案。
JAVA:nutch吆寨,hetrix...etc赏淌。這幾個(gè)更適合做通用爬蟲(chóng)或少量的定制爬蟲(chóng),相對(duì)scrapy優(yōu)點(diǎn)是資料比較多啄清,成熟六水。不過(guò)用java系的寫(xiě)大量定制爬蟲(chóng)應(yīng)該比較痛苦。
Ruby:不了解辣卒,僅聽(tīng)說(shuō)ruby有個(gè)爬蟲(chóng)庫(kù)掷贾。
Node.js:遇到有個(gè)初創(chuàng)團(tuán)隊(duì)用node.js寫(xiě)的,負(fù)責(zé)人有scrapy(<0.16)荣茫,gevent經(jīng)驗(yàn)想帅。不了解。
python:gevent及其他py的爬蟲(chóng)框架啡莉。稍后會(huì)詳細(xì)描述這部分港准。
對(duì)于gevent上寫(xiě)爬蟲(chóng)的各位,我只能說(shuō)你們有實(shí)力咧欣,你們?yōu)楹我燧喿硬嫒ぃ銈兛隙ㄓ凶约旱睦碛傻模扑]參考下scrapy造輪子该押。gevent寫(xiě)爬蟲(chóng)大概的方案是gevent+requests+一個(gè)隊(duì)列庫(kù)(redis,beanstalk.etc.)疗杉。需要注意的點(diǎn)和坑有如下一些。
0,gevent使用協(xié)程蚕礼,monkey_patch后一些調(diào)試方法不可用烟具。
1,requests的編碼檢測(cè)是不符標(biāo)準(zhǔn)的奠蹬,他有兩個(gè)編碼朝聋,一個(gè)是http head里面的編碼,另一個(gè)是依據(jù)網(wǎng)頁(yè)body的編碼囤躁。標(biāo)準(zhǔn)是網(wǎng)頁(yè)內(nèi)容聲明的編碼優(yōu)先于http頭的編碼冀痕,requests沒(méi)有做這個(gè)考慮,總是使用head里面的編碼狸演。在head和body編碼聲明不一致時(shí)可能出現(xiàn)編碼錯(cuò)誤言蛇。
2,gevent的同步機(jī)制略少,某些情況下協(xié)程同步效率低宵距。這個(gè)是我在寫(xiě)http代理調(diào)度器(類(lèi)似Crawlera)的東西時(shí)遇到的腊尚。http代理調(diào)度器我下面會(huì)提及。
3,其他各種細(xì)節(jié)满哪。太多婿斥。如requests開(kāi)gzip劝篷,requests連接池等等。太多太多民宿。
gevent相對(duì)于scrapy的優(yōu)點(diǎn)有:
1,如果涉及到底層定制 娇妓,gevent比scrapy所用的twisted簡(jiǎn)單。我曾想給scrapy嵌一個(gè)http代理調(diào)度功能活鹰,發(fā)現(xiàn)略難峡蟋,需要很了解twisted。
2,如果你只需要很少的幾個(gè)簡(jiǎn)單爬蟲(chóng)华望,你可能覺(jué)得gevent用著更順手(但scrapy也很容易)。對(duì)于純下載網(wǎng)頁(yè)仅乓,用gevent實(shí)現(xiàn)比scrapy快赖舟,畢竟scrapy還有其他功能,但這有個(gè)前提夸楣,你有很高很高的帶寬宾抓,要先達(dá)到scrapy的下載頁(yè)面速率上限。
python還有其他幾個(gè)爬蟲(chóng)框架豫喧,我都大致看過(guò)源碼石洗。有個(gè)框架有個(gè)讓你人工輸驗(yàn)證碼的demo(名字忘了)。其他沒(méi)什么特別的了紧显。
scrapy經(jīng)驗(yàn)讲衫,資料
資料:官方文檔,http權(quán)威指南孵班,一些博文涉兽。
看文檔時(shí)仔細(xì)點(diǎn),很多功能都有篙程。
scrapy github賬號(hào)的各類(lèi)repo(https://github.com/scrapinghub)有很多好東西枷畏,如:
1,scrapyjs,splash:爬蟲(chóng)遇到的js問(wèn)題的解決方法(JS解析會(huì)在下面提及)
2,webstruct...etc:機(jī)器學(xué)習(xí),模糊匹配等用來(lái)解析網(wǎng)頁(yè)內(nèi)容的虱饿。
3,etc...
scrapy有個(gè)SEP類(lèi)似PEP的拥诡,可以一看,也在github的倉(cāng)庫(kù)氮发。
留意scrapy的博客http://blog.scrapinghub.com/
wiki:https://github.com/scrapy/scrapy/wiki
scrapy公司(http://scrapinghub.com/)的產(chǎn)品:
1,定制爬蟲(chóng)(讓scrapy公司幫你寫(xiě)爬蟲(chóng)然后交付你)
2,scrapy cloud(提供跑爬蟲(chóng)的服務(wù)器(scrapyd))
3,autoscraping(點(diǎn)擊需要內(nèi)容即可實(shí)現(xiàn)爬取)
4,crawlera,解決爬網(wǎng)站的ip限制問(wèn)題(我有一個(gè)類(lèi)似功能的本地版http代理調(diào)度器及大量代理)渴肉。
一些常見(jiàn)問(wèn)題,經(jīng)驗(yàn):
0,了解scrapy已經(jīng)做過(guò)的功能爽冕,優(yōu)化等宾娜。。扇售。防止重復(fù)造輪子前塔,如嚣艇,去重,編碼檢測(cè)华弓,dns緩存食零,http長(zhǎng)連接,gzip等等。
1,JS相關(guān)寂屏。
這個(gè)是被問(wèn)的最多的贰谣。看具體情況解決迁霎≈ǜВ可模擬相關(guān)js執(zhí)行、繞過(guò)考廉,或直接調(diào)瀏覽器去訪問(wèn)秘豹。自己用一個(gè)JS引擎+模擬一個(gè)瀏覽器環(huán)境難度太大了(參見(jiàn)V8的DEMO)。
調(diào)瀏覽器有很多方法昌粤。難以細(xì)說(shuō)既绕,關(guān)鍵字如下,selenium涮坐,phantomjs凄贩,casperjs,ghost袱讹,webkit疲扎,scrapyjs,splash捷雕。一些細(xì)節(jié)如關(guān)掉CSS渲染评肆,圖片加載等。只有scrapyjs是完全異步的非区,相對(duì)是速度最快的瓜挽,scrapyjs將webkit的事件循環(huán)和twisted的事件循環(huán)合在一起了。其他的方案要么阻塞征绸,要么用多進(jìn)程久橙。簡(jiǎn)單的js需求(對(duì)效率要求不高)隨意選,最優(yōu)方案是scrapyjs+定制webkit(去掉不需要的功能)管怠。調(diào)瀏覽器開(kāi)頁(yè)面是比較耗資源的(主要是cpu)
2,內(nèi)容解析淆衷。
XPATH就可以了,感興趣可以看下pyquery渤弛,css選擇器祝拯。
如果想獲得網(wǎng)頁(yè)對(duì)應(yīng)的txt,可以調(diào)瀏覽器,有個(gè)類(lèi)似plain_txt的接口可以獲取網(wǎng)頁(yè)保存成txt佳头。
模糊匹配參考scrapy github里面幾個(gè)庫(kù)鹰贵,機(jī)器學(xué)習(xí)不一定好用(效果問(wèn)題,人工問(wèn)題-需要訓(xùn)練)康嘉。還有寫(xiě)些正則去模糊匹配碉输。
新聞?lì)愃频恼奶崛∮衦eadability,boilerplate。
3,分布式亭珍。
首先考慮按任務(wù)(目標(biāo))切分敷钾,然后讓不同目標(biāo)的爬蟲(chóng)在不同機(jī)器上跑
完全的對(duì)等分布式(多爬蟲(chóng)爬一個(gè)目標(biāo)),把任務(wù)隊(duì)列替換掉爬蟲(chóng)改改即可肄梨。github里面有幾個(gè)現(xiàn)有的實(shí)現(xiàn)參考阻荒。
分布式需求可能是偽命題。想清楚為何要分布式众羡。硬件夠不夠侨赡,像什么拿一個(gè)不支持持久化的url隊(duì)列的爬蟲(chóng)說(shuō)量大需要分布式的,我只能默念纱控,你為何這么吊。
4,部署菜秦,調(diào)度
部署推薦scrapyd甜害。這也是官方推薦的方法。
大量爬蟲(chóng)的調(diào)度球昨,這個(gè)目前(13-10)沒(méi)有現(xiàn)成的合適方法尔店,期望是實(shí)現(xiàn)爬蟲(chóng)的某些配置放數(shù)據(jù)庫(kù),提供web后臺(tái) 主慰,然后按配置周期嚣州、定時(shí)運(yùn)行爬蟲(chóng),終止共螺,暫停爬蟲(chóng)等等该肴。可以實(shí)現(xiàn)藐不,但要自己寫(xiě)不少東西匀哄。
5,ip限制問(wèn)題
買(mǎi)的起大量ip的可買(mǎi)(買(mǎi)大量同網(wǎng)段爬可能導(dǎo)致整網(wǎng)段被封)。
找大量免費(fèi)的開(kāi)放http代理雏蛮,篩選可用的涎嚼,免費(fèi)開(kāi)放代理不可靠,寫(xiě)個(gè)調(diào)度機(jī)制挑秉,自動(dòng)根據(jù)成功次數(shù)法梯,延遲等選擇合適代理,這個(gè)功能難以在scrapy內(nèi)實(shí)現(xiàn)犀概,參考scrapinghub的crawlera立哑,我完成了一個(gè)本地版夜惭。
6,url去重。
如果有千萬(wàn)級(jí)的URL需要去重刁憋,需要仔細(xì)看下scrapy的去重機(jī)制和bloom filter(布隆過(guò)濾器)滥嘴。bloomfilter有個(gè)公式可以算需要多少內(nèi)存。另bloomfilter + scrapy在github有現(xiàn)有實(shí)現(xiàn)可以參考至耻。
7,存儲(chǔ)若皱。
mongodb,mongodb不滿足某些功能時(shí)考慮hbase,參考http://blog.scrapinghub.com/2013/05/13/mongo-bad-for-scraped-data/
8,硬件扛不住別玩爬蟲(chóng)尘颓。走触。。曾在I3 4G 1T上跑爬蟲(chóng)疤苹』ス悖卡在磁盤(pán)io(量大,磁盤(pán)io差卧土,內(nèi)存低)惫皱,出現(xiàn)內(nèi)存占用飆升。很難調(diào)試(調(diào)試爬蟲(chóng)看實(shí)際跑耗時(shí)較長(zhǎng))尤莺,初步以為是爬蟲(chóng)有問(wèn)題內(nèi)存占用高導(dǎo)致數(shù)據(jù)庫(kù)卡旅敷。調(diào)試結(jié)果確認(rèn)為,配置低量太大颤霎,導(dǎo)致數(shù)據(jù)庫(kù)慢媳谁,數(shù)據(jù)庫(kù)慢之后爬蟲(chóng)任務(wù)隊(duì)列占滿內(nèi)存并開(kāi)始寫(xiě)磁盤(pán),又循環(huán)導(dǎo)致數(shù)據(jù)庫(kù)慢友酱。
9晴音,爬蟲(chóng)監(jiān)控
scrapyd自帶簡(jiǎn)單的監(jiān)控,不夠的話用scrapy的webservice自己寫(xiě)缔杉,暫無(wú)(13.10)現(xiàn)成的
9,=锤躁。=想到再補(bǔ)充。