自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

大規(guī)模爬蟲流程總結(jié)

大數(shù)據(jù)
爬蟲是一個(gè)比較容易上手的技術(shù),也許花5分鐘看一篇文檔就能爬取單個(gè)網(wǎng)頁(yè)上的數(shù)據(jù)。但對(duì)于大規(guī)模爬蟲,完全就是另一回事,并不是1*n這么簡(jiǎn)單,還會(huì)衍生出許多別的問(wèn)題。

爬蟲是一個(gè)比較容易上手的技術(shù),也許花5分鐘看一篇文檔就能爬取單個(gè)網(wǎng)頁(yè)上的數(shù)據(jù)。但對(duì)于大規(guī)模爬蟲,完全就是另一回事,并不是1*n這么簡(jiǎn)單,還會(huì)衍生出許多別的問(wèn)題。

系統(tǒng)的大規(guī)模爬蟲流程如圖所示。

 

系統(tǒng)的大規(guī)模爬蟲流程

 

先檢查是否有API

API是網(wǎng)站官方提供的數(shù)據(jù)接口,如果通過(guò)調(diào)用API采集數(shù)據(jù),則相當(dāng)于在網(wǎng)站允許的范圍內(nèi)采集,這樣既不會(huì)有道德法律風(fēng)險(xiǎn),也沒(méi)有網(wǎng)站故意設(shè)置的障礙;不過(guò)調(diào)用API接口的訪問(wèn)則處于網(wǎng)站的控制中,網(wǎng)站可以用來(lái)收費(fèi),可以用來(lái)限制訪問(wèn)上限等。整體來(lái)看,如果數(shù)據(jù)采集的需求并不是很獨(dú)特,那么有API則應(yīng)優(yōu)先采用調(diào)用API的方式。

數(shù)據(jù)結(jié)構(gòu)分析和數(shù)據(jù)存儲(chǔ)

  • 爬蟲需求要十分清晰,具體表現(xiàn)為需要哪些字段,這些字段可以是網(wǎng)頁(yè)上現(xiàn)有的,也可以是根據(jù)網(wǎng)頁(yè)上現(xiàn)有的字段進(jìn)一步計(jì)算的,這些字段如何構(gòu)建表,多張表如何連接等。值得一提的是,確定字段環(huán)節(jié),不要只看少量的網(wǎng)頁(yè),因?yàn)閱蝹€(gè)網(wǎng)頁(yè)可以缺少別的同類網(wǎng)頁(yè)的字段,這既有可能是由于網(wǎng)站的問(wèn)題,也可能是用戶行為的差異,只有多觀察一些網(wǎng)頁(yè)才能綜合抽象出具有普適性的關(guān)鍵字段——這并不是幾分鐘看幾個(gè)網(wǎng)頁(yè)就可以決定的簡(jiǎn)單事情,如果遇上了那種臃腫、混亂的網(wǎng)站,可能坑非常多。
  • 對(duì)于大規(guī)模爬蟲,除了本身要采集的數(shù)據(jù)外,其他重要的中間數(shù)據(jù)(比如頁(yè)面Id或者url)也建議存儲(chǔ)下來(lái),這樣可以不必每次重新爬取id。
  • 數(shù)據(jù)庫(kù)并沒(méi)有固定的選擇,本質(zhì)仍是將Python里的數(shù)據(jù)寫到庫(kù)里,可以選擇關(guān)系型數(shù)據(jù)庫(kù)MySQL等,也可以選擇非關(guān)系型數(shù)據(jù)庫(kù)MongoDB等;對(duì)于普通的結(jié)構(gòu)化數(shù)據(jù)一般存在關(guān)系型數(shù)據(jù)庫(kù)即可。sqlalchemy是一個(gè)成熟好用的數(shù)據(jù)庫(kù)連接框架,其引擎可與Pandas配套使用,把數(shù)據(jù)處理和數(shù)據(jù)存儲(chǔ)連接起來(lái),一氣呵成。

數(shù)據(jù)流分析

  • 對(duì)于要批量爬取的網(wǎng)頁(yè),往上一層,看它的入口在哪里;這個(gè)是根據(jù)采集范圍來(lái)確定入口,比如若只想爬一個(gè)地區(qū)的數(shù)據(jù),那從該地區(qū)的主頁(yè)切入即可;但若想爬全國(guó)數(shù)據(jù),則應(yīng)更往上一層,從全國(guó)的入口切入。一般的網(wǎng)站網(wǎng)頁(yè)都以樹(shù)狀結(jié)構(gòu)為主,找到切入點(diǎn)作為根節(jié)點(diǎn)一層層往里進(jìn)入即可。
  • 值得注意的一點(diǎn)是,一般網(wǎng)站都不會(huì)直接把全量的數(shù)據(jù)做成列表給你一頁(yè)頁(yè)往下翻直到遍歷完數(shù)據(jù),比如鏈家上面很清楚地寫著有24587套二手房,但是它只給100頁(yè),每頁(yè)30個(gè),如果直接這么切入只能訪問(wèn)3000個(gè),遠(yuǎn)遠(yuǎn)低于真實(shí)數(shù)據(jù)量;因此先切片,再整合的數(shù)據(jù)思維可以獲得更大的數(shù)據(jù)量。顯然100頁(yè)是系統(tǒng)設(shè)定,只要超過(guò)300個(gè)就只顯示100頁(yè),因此可以通過(guò)其他的篩選條件不斷細(xì)分,只到篩選結(jié)果小于等于300頁(yè)就表示該條件下沒(méi)有缺漏;最后把各種條件下的篩選結(jié)果集合在一起,就能夠盡可能地還原真實(shí)數(shù)據(jù)量。
  • 明確了大規(guī)模爬蟲的數(shù)據(jù)流動(dòng)機(jī)制,下一步就是針對(duì)單個(gè)網(wǎng)頁(yè)進(jìn)行解析,然后把這個(gè)模式復(fù)制到整體。對(duì)于單個(gè)網(wǎng)頁(yè),采用抓包工具可以查看它的請(qǐng)求方式,是get還是post,有沒(méi)有提交表單,欲采集的數(shù)據(jù)是寫入源代碼里還是通過(guò)AJAX調(diào)用JSON數(shù)據(jù)。
  • 同樣的道理,不能只看一個(gè)頁(yè)面,要觀察多個(gè)頁(yè)面,因?yàn)榕颗老x要弄清這些大量頁(yè)面url以及參數(shù)的規(guī)律,以便可以自動(dòng)構(gòu)造;有的網(wǎng)站的url以及關(guān)鍵參數(shù)是加密的,這樣就悲劇了,不能靠著明顯的邏輯直接構(gòu)造,這種情況下要批量爬蟲,要么找到它加密的js代碼,在爬蟲代碼上加入從明文到密碼的加密過(guò)程;要么采用下文所述的模擬瀏覽器的方式。

數(shù)據(jù)采集

之前用R做爬蟲,不要笑,R的確可以做爬蟲工作;但在爬蟲方面,Python顯然優(yōu)勢(shì)更明顯,受眾更廣,這得益于其成熟的爬蟲框架,以及其他的在計(jì)算機(jī)系統(tǒng)上更好的性能。scrapy是一個(gè)成熟的爬蟲框架,直接往里套用就好,比較適合新手學(xué)習(xí);requests是一個(gè)比原生的urllib包更簡(jiǎn)潔強(qiáng)大的包,適合作定制化的爬蟲功能。requests主要提供一個(gè)基本訪問(wèn)功能,把網(wǎng)頁(yè)的源代碼給download下來(lái)。一般而言,只要加上跟瀏覽器同樣的Requests Headers參數(shù),就可以正常訪問(wèn),status_code為200,并成功得到網(wǎng)頁(yè)源代碼;但是也有某些反爬蟲較為嚴(yán)格的網(wǎng)站,這么直接訪問(wèn)會(huì)被禁止;或者說(shuō)status為200也不會(huì)返回正常的網(wǎng)頁(yè)源碼,而是要求寫驗(yàn)證碼的js腳本等。

下載到了源碼之后,如果數(shù)據(jù)就在源碼中,這種情況是最簡(jiǎn)單的,這就表示已經(jīng)成功獲取到了數(shù)據(jù),剩下的無(wú)非就是數(shù)據(jù)提取、清洗、入庫(kù)。但若網(wǎng)頁(yè)上有,然而源代碼里沒(méi)有的,就表示數(shù)據(jù)寫在其他地方,一般而言是通過(guò)AJAX異步加載JSON數(shù)據(jù),從XHR中找即可找到;如果這樣還找不到,那就需要去解析js腳本了。

解析工具

源碼下載后,就是解析數(shù)據(jù)了,常用的有兩種方法,一種是用BeautifulSoup對(duì)樹(shù)狀HTML進(jìn)行解析,另一種是通過(guò)正則表達(dá)式從文本中抽取數(shù)據(jù)。

  • BeautifulSoup比較簡(jiǎn)單,支持Xpath和CSSSelector兩種途徑,而且像Chrome這類瀏覽器一般都已經(jīng)把各個(gè)結(jié)點(diǎn)的Xpath或者CSSSelector標(biāo)記好了,直接復(fù)制即可。以CSSSelector為例,可以選擇tag、id、class等多種方式進(jìn)行定位選擇,如果有id建議選id,因?yàn)楦鶕?jù)HTML語(yǔ)法,一個(gè)id只能綁定一個(gè)標(biāo)簽。
  • 正則表達(dá)式很強(qiáng)大,但構(gòu)造起來(lái)有點(diǎn)復(fù)雜,需要專門去學(xué)習(xí)。因?yàn)橄螺d下來(lái)的源碼格式就是字符串,所以正則表達(dá)式可以大顯身手,而且處理速度很快。

對(duì)于HTML結(jié)構(gòu)固定,即同樣的字段處tag、id和class名稱都相同,采用BeautifulSoup解析是一種簡(jiǎn)單高效的方案,但有的網(wǎng)站混亂,同樣的數(shù)據(jù)在不同頁(yè)面間HTML結(jié)構(gòu)不同,這種情況下BeautifulSoup就不太好使;如果數(shù)據(jù)本身格式固定,則用正則表達(dá)式更方便。比如以下的例子,這兩個(gè)都是深圳地區(qū)某個(gè)地方的經(jīng)度,但一個(gè)頁(yè)面的class是long,一個(gè)頁(yè)面的class是longitude,根據(jù)class來(lái)選擇就沒(méi)辦法同時(shí)滿足2個(gè),但只要注意到深圳地區(qū)的經(jīng)度都是介于113到114之間的浮點(diǎn)數(shù),就可以通過(guò)正則表達(dá)式”11[3-4].\d+”來(lái)使兩個(gè)都滿足。

 

 

數(shù)據(jù)整理

一般而言,爬下來(lái)的原始數(shù)據(jù)都不是清潔的,所以在入庫(kù)前要先整理;由于大部分都是字符串,所以主要也就是字符串的處理方式了。

  • 字符串自帶的方法可以滿足大部分簡(jiǎn)單的處理需求,比如strip()可以去掉首尾不需要的字符或者換行符等,replace()可以將指定部分替換成需要的部分,split()可以在指定部分分割然后截取一部分。
  • 如果字符串處理的需求太復(fù)雜以致常規(guī)的字符串處理方法不好解決,那就要請(qǐng)出正則表達(dá)式這個(gè)大殺器。
  • Pandas是Python中常用的數(shù)據(jù)處理模塊,雖然作為一個(gè)從R轉(zhuǎn)過(guò)來(lái)的人一直覺(jué)得這個(gè)模仿R的包實(shí)在是太難用了。Pandas不僅可以進(jìn)行向量化處理、篩選、分組、計(jì)算,還能夠整合成DataFrame,將采集的數(shù)據(jù)整合成一張表,呈現(xiàn)最終的存儲(chǔ)效果。

寫入數(shù)據(jù)庫(kù)

如果只是中小規(guī)模的爬蟲,可以把最后的爬蟲結(jié)果匯合成一張表,最后導(dǎo)出成一張表格以便后續(xù)使用;但對(duì)于表數(shù)量多、單張表容量大的大規(guī)模爬蟲,再導(dǎo)出成一堆零散的表就不合適了,肯定還是要放在數(shù)據(jù)庫(kù)中,既方便存儲(chǔ),也方便進(jìn)一步整理。

  • 寫入數(shù)據(jù)庫(kù)有兩種方法,一種是通過(guò)Pandas的DataFrame自帶的to_sql()方法,好處是自動(dòng)建表,對(duì)于對(duì)表結(jié)構(gòu)沒(méi)有嚴(yán)格要求的情況下可以采用這種方式,不過(guò)值得一提的是,如果是多行的DataFrame可以直接插入不加索引,但若只有一行就要加索引否則報(bào)錯(cuò),雖然這個(gè)認(rèn)為不太合理;另一種是利用數(shù)據(jù)庫(kù)引擎來(lái)執(zhí)行SQL語(yǔ)句,這種情況下要先自己建表,雖然多了一步,但是表結(jié)構(gòu)完全是自己控制之下。Pandas與SQL都可以用來(lái)建表、整理數(shù)據(jù),結(jié)合起來(lái)使用效率更高。
  • 寫入數(shù)據(jù)庫(kù)有兩種思路,一種是等所有的數(shù)據(jù)都爬完,集中一次向量化清洗,一次性入庫(kù);另一種是爬一次數(shù)據(jù)清洗一次就入庫(kù)。表面上看前者效率更高,但是對(duì)于大規(guī)模爬蟲,穩(wěn)定性也是要考慮的重要因素,因?yàn)樵陂L(zhǎng)久的爬蟲過(guò)程中,總不可避免會(huì)出現(xiàn)一些網(wǎng)絡(luò)錯(cuò)誤,甚至如果出現(xiàn)斷網(wǎng)斷電的情況,第一種情況下就全白費(fèi)了,第二種情況下至少已入庫(kù)的不會(huì)受影響,并且單次的清洗和入庫(kù)是很快的,基本不怎么費(fèi)時(shí)間,所以整體來(lái)看推薦第二種思路。

爬蟲效率提升

對(duì)于大規(guī)模爬蟲,效率是一個(gè)核心問(wèn)題。單個(gè)網(wǎng)頁(yè)爬取可能很大,一旦網(wǎng)頁(yè)數(shù)量級(jí)大增之后,任務(wù)量也會(huì)大增,同時(shí)方式下的耗時(shí)也會(huì)大增。沒(méi)有公司或人個(gè)愿意爬個(gè)幾十萬(wàn)上百萬(wàn)的頁(yè)面還要等幾個(gè)月,因此優(yōu)化流程、提高效率是非常必要的。

  • 盡量減少訪問(wèn)次數(shù)。單次爬蟲的主要耗時(shí)在于網(wǎng)絡(luò)請(qǐng)求等待響應(yīng),所以能減少訪問(wèn)就少訪問(wèn),既減少自己的工作量,也減輕網(wǎng)站的壓力,還降低被封的風(fēng)險(xiǎn)。首先要做的就是流程優(yōu)化,盡可能精簡(jiǎn)流程,一些數(shù)據(jù)如果可以在一個(gè)頁(yè)面內(nèi)獲取而不必非要在多個(gè)頁(yè)面下獲取,那就只在一個(gè)頁(yè)面內(nèi)獲取。然后去重也是非常重要的手段——網(wǎng)站并不是嚴(yán)格意義的互不交叉的樹(shù)狀結(jié)構(gòu),而是多重交叉的網(wǎng)狀結(jié)構(gòu),所以從多個(gè)入口深入的網(wǎng)頁(yè)會(huì)有很多重復(fù),一般根據(jù)url或者id進(jìn)行唯一性判別,爬過(guò)的就不再繼續(xù)爬了。最后,值得深思的一點(diǎn)就是,是不是所有的數(shù)據(jù)都需要爬?對(duì)于那些響應(yīng)慢,反爬機(jī)制很嚴(yán)格的網(wǎng)站,爬少量的都困難,爬大量的時(shí)間成本就會(huì)高到難以接受,這種情況下怎么辦?舉一個(gè)例子,對(duì)于氣象數(shù)據(jù),已知的一點(diǎn)是時(shí)間、空間越接近的地方數(shù)據(jù)就越接近,那么你爬了一個(gè)點(diǎn)的氣象數(shù)據(jù)之后,100米以內(nèi)的另一個(gè)點(diǎn)就可以不用再爬,因?yàn)榭深A(yù)期一定是跟之前的點(diǎn)差不多;這個(gè)時(shí)候就可以采用機(jī)器學(xué)習(xí)的方法,爬取一部分?jǐn)?shù)據(jù)作為訓(xùn)練數(shù)據(jù),其他的進(jìn)行預(yù)測(cè),當(dāng)對(duì)數(shù)據(jù)的準(zhǔn)確性要求不是特別高,當(dāng)模型的性能比較好,采用機(jī)器學(xué)習(xí)模型預(yù)測(cè)就可以省下大部分爬蟲的工作。雖然專業(yè)的爬蟲工程師懂機(jī)器學(xué)習(xí)的可能不多,但這正是復(fù)合型人才的優(yōu)勢(shì)。
  • 大量爬蟲是一個(gè)IO阻塞的任務(wù),因此采用多進(jìn)程、多線程或者協(xié)程的并發(fā)方式可以有效地提高整理速度。個(gè)人推薦用協(xié)程,速度比較快,穩(wěn)定性也比較好。
  • 即使把各種法子都用盡了,單機(jī)單位時(shí)間內(nèi)能爬的網(wǎng)頁(yè)數(shù)仍是有限的,面對(duì)大量的頁(yè)面隊(duì)列,可計(jì)算的時(shí)間仍是很長(zhǎng),這種時(shí)候就必須要用機(jī)器換時(shí)間了,這就是分布式爬蟲。首先,分布式不是爬蟲的本質(zhì),也不是必須的,對(duì)于互相獨(dú)立、不存在通信的任務(wù)就可手動(dòng)對(duì)任務(wù)分割,然后在多臺(tái)機(jī)器上分別執(zhí)行,減少每臺(tái)機(jī)器的工作量,耗時(shí)就會(huì)成倍減少。比如有100W個(gè)頁(yè)面待爬,可以用5臺(tái)機(jī)器分別爬互不重復(fù)的20W個(gè)頁(yè)面,相對(duì)單機(jī)耗時(shí)就縮短了5倍。但是如果存在著需要通信的狀況,比如一個(gè)變動(dòng)的待爬隊(duì)列,每爬一次這個(gè)隊(duì)列就會(huì)發(fā)生變化,即使分割任務(wù)也就有交叉重復(fù),因?yàn)楦鱾€(gè)機(jī)器在程序運(yùn)行時(shí)的待爬隊(duì)列都不一樣了——這種情況下只能用分布式,一個(gè)Master存儲(chǔ)隊(duì)列,其他多個(gè)Slave各自來(lái)取,這樣共享一個(gè)隊(duì)列,取的時(shí)候互斥也不會(huì)重復(fù)爬取。scrapy-redis是一款用得比較多的分布式爬蟲框架。

數(shù)據(jù)質(zhì)量管理

大量的頁(yè)面往往不會(huì)是結(jié)構(gòu)完全一樣,而且大量的訪問(wèn)也總會(huì)出現(xiàn)該訪問(wèn)成功卻訪問(wèn)不成功的情況,這些都是非常常見(jiàn)的狀況,因此單一的邏輯無(wú)法應(yīng)對(duì)各種不可預(yù)知的問(wèn)題,反映在結(jié)果上就是爬取的數(shù)據(jù)往往會(huì)有錯(cuò)漏的情況。

  • try...except是Python中常用的異常診斷語(yǔ)句,在爬蟲中也可充分應(yīng)用。一方面,同樣的字段可能在有的網(wǎng)頁(yè)上有,另外的網(wǎng)頁(yè)上就是沒(méi)有,這樣爬取該字段的語(yǔ)句就會(huì)出錯(cuò),然而這并不是自己邏輯或代碼的錯(cuò),用診斷語(yǔ)句就可以繞過(guò)這些網(wǎng)站的坑;另一方面,大規(guī)模爬蟲是一個(gè)耗時(shí)較長(zhǎng)的過(guò)程,就像是千軍萬(wàn)馬沖鋒,不能因?yàn)橹虚g掛了幾個(gè)而停止整體進(jìn)程,所以采用這個(gè)語(yǔ)句可以跳過(guò)中間出現(xiàn)的各種自己產(chǎn)生或者網(wǎng)站產(chǎn)生的錯(cuò)誤,保證爬蟲整體的持續(xù)進(jìn)行。
  • 斷點(diǎn)續(xù)傳也是流程設(shè)計(jì)是重要的一塊。一個(gè)一旦啟動(dòng)就必須要等它跑完,如果中途中斷就前功盡棄的爬蟲系統(tǒng)是非常不健壯的,因?yàn)檎l(shuí)也無(wú)法預(yù)料中間會(huì)因各種原因中斷,而且估計(jì)也沒(méi)有誰(shuí)會(huì)喜歡這種類似于被綁架的感覺(jué)。健壯的爬蟲系統(tǒng)應(yīng)該是隨時(shí)都可以啟動(dòng),而且每次啟動(dòng)都是爬剩下的而不是從頭開(kāi)始重復(fù)爬,其實(shí)這個(gè)流程設(shè)計(jì)也比較簡(jiǎn)單,如下圖所示:所有待爬的網(wǎng)頁(yè)total_urls分為兩部分,一部分是已爬過(guò)的gotten_urls(初始化之前為空),total_urls與gotten_urls的差集remained_urls就是剩余要爬的網(wǎng)頁(yè)。total_urls是固定的,每執(zhí)行一次爬蟲,gotten_urls就會(huì)增加,下一次啟動(dòng)爬蟲程序計(jì)算的remained_urls就減少了,當(dāng)remained_urls為空表示完成全部爬蟲任務(wù)。這樣的斷點(diǎn)續(xù)傳流程設(shè)計(jì)可使爬蟲程序可以隨時(shí)停下,隨時(shí)啟動(dòng),并且每次啟動(dòng)都不會(huì)做重復(fù)勞動(dòng)。

 

錯(cuò)漏校驗(yàn)可以入庫(kù)之后進(jìn)行,這一步就是把爬蟲過(guò)程中產(chǎn)生錯(cuò)漏的記錄篩選出來(lái)清掉重新爬,這一步也很重要,保證數(shù)據(jù)質(zhì)量才能繼續(xù)后續(xù)的流程。錯(cuò)漏校驗(yàn)就要結(jié)合業(yè)務(wù)自己來(lái)寫一套數(shù)據(jù)清洗流程。對(duì)于字段為空的情況,有兩種產(chǎn)生原因:一是該網(wǎng)頁(yè)本來(lái)就沒(méi)有這個(gè)字段,這不是錯(cuò)誤;另一種是由于網(wǎng)絡(luò)出錯(cuò)沒(méi)有獲取到該字段,這是錯(cuò)誤,要篩選出來(lái)清除——一般情況下可以通過(guò)status_code是否為200來(lái)判斷網(wǎng)絡(luò)訪問(wèn)是否出錯(cuò)來(lái)判斷空字段是否是由于網(wǎng)絡(luò)出錯(cuò)的原因造成的,對(duì)于特殊的status_code為200仍不返回正常數(shù)據(jù)的就需特殊分析了。此外,可以通過(guò)某些字段固定的屬性來(lái)作為篩選條件,比如名稱不能為空(或者為空就舍棄)、深圳地區(qū)的經(jīng)度介于113和114之間等條件來(lái)過(guò)濾掉缺漏或者是網(wǎng)站反爬惡意傳回的錯(cuò)誤數(shù)據(jù)。清洗邏輯越全面復(fù)雜,數(shù)據(jù)質(zhì)量越高,后續(xù)使用數(shù)據(jù)時(shí)產(chǎn)生的問(wèn)題就越少;這也是一塊需要深入思考的部分。

反反爬蟲

爬蟲的固定套路也就那么多,各種網(wǎng)站爬取策略的不同就在于網(wǎng)站的反爬蟲機(jī)制不同,因此多作試驗(yàn),摸清網(wǎng)站的反爬機(jī)制,是大規(guī)模爬蟲的先行工作。爬蟲與反爬蟲是無(wú)休止的斗爭(zhēng),也是一個(gè)見(jiàn)招拆招的過(guò)程,但總體來(lái)說(shuō),以下方法可以繞過(guò)常見(jiàn)的反爬蟲。

加上headers。這是最基礎(chǔ)的手段。加上了請(qǐng)求頭就可以偽裝成瀏覽器,混過(guò)反爬的第一道關(guān)卡;反之,連請(qǐng)求頭都不加,網(wǎng)站可以直接看出是程序在訪問(wèn)而直接拒絕。一般的網(wǎng)站加上User-Agent就可以,反爬嚴(yán)格的網(wǎng)站則要加上cookie甚至各種參數(shù)都要加上。

隨機(jī)延時(shí)。這是最簡(jiǎn)單有效的一種手段。穩(wěn)定性是大規(guī)模爬蟲的另一個(gè)核心問(wèn)題,雖然與效率沖突。許多網(wǎng)站都會(huì)統(tǒng)計(jì)同一個(gè)IP一段時(shí)間內(nèi)的訪問(wèn)頻率,如果采集過(guò)快,會(huì)直接封禁IP。不要為了一時(shí)爽而不加延時(shí)導(dǎo)致幾分鐘后IP就被封24小時(shí),還不如老老實(shí)實(shí)地加延時(shí)慢慢爬一夜爬完。至于延時(shí)加多少因各個(gè)網(wǎng)站而異,但一般情況下延時(shí)個(gè)3~5秒就足夠了。

如果頁(yè)面量實(shí)在太大,每次訪問(wèn)設(shè)置的隨時(shí)延時(shí)也會(huì)成為額外大量的時(shí)間成本。單個(gè)IP快速訪問(wèn)會(huì)有被封的風(fēng)險(xiǎn),這是就要用代理池,有兩點(diǎn)好處:一是降低某個(gè)IP單位時(shí)間內(nèi)的訪問(wèn)頻率,降低被封風(fēng)險(xiǎn);二是即使IP被封,也有別的IP可以繼續(xù)訪問(wèn)。代理池有免費(fèi)和收費(fèi)的,免費(fèi)代理可以從許多網(wǎng)站上獲取(這也是一個(gè)爬蟲項(xiàng)目),但大部分都沒(méi)用,有用的小部分也會(huì)很快掛掉;收費(fèi)代理好一點(diǎn),但也好不了多少。高質(zhì)量的代理成本就高了不少,這個(gè)要結(jié)合項(xiàng)目實(shí)際需求來(lái)考慮成本。所以,如果網(wǎng)站不封IP就可以不用代理,以免減慢訪問(wèn)速度,增大被拒的概率。

有的網(wǎng)站必須要登錄才能訪問(wèn),才能爬蟲。以知乎為例,知乎的模擬登錄必較簡(jiǎn)單,甚至現(xiàn)在都沒(méi)有對(duì)帳號(hào)和密碼加密,直接明文post就可以。請(qǐng)求頭的cookie含有登錄信息,而知乎的cookie壽命較長(zhǎng),所以可以直接在網(wǎng)站上人工登錄然后把cookie復(fù)制到代碼中;知乎目前的反爬機(jī)制是如果判斷是機(jī)器人就封帳號(hào)但不封IP——封IP是同樣的機(jī)器無(wú)法訪問(wèn),但卻可以用同樣的帳號(hào)在其他機(jī)器上訪問(wèn);封號(hào)是同樣的帳號(hào)在各種終端上都無(wú)法訪問(wèn),但同一臺(tái)機(jī)器上卻可以換號(hào)訪問(wèn)?;谶@種機(jī)制,爬知乎就不需要IP代理池而需要的是帳號(hào)池。舉另一個(gè)例子,騰訊有一個(gè)子網(wǎng)站,它也要求必須QQ登錄,而且cookie只有6分鐘的壽命,而且一個(gè)帳號(hào)一天只能訪問(wèn)130次超過(guò)就封號(hào),無(wú)論爬得再慢——這種情況下只能搞大量的QQ號(hào)進(jìn)行自動(dòng)登錄并不斷切換。

如果有的網(wǎng)站的反爬機(jī)制實(shí)在太過(guò)喪心病狂,各種JS代碼邏輯十分復(fù)雜艱深,那只能模擬瀏覽器了。模擬瀏覽器其實(shí)就是一種自動(dòng)的瀏覽器訪問(wèn),與正常的用戶訪問(wèn)很類似,所以可以跳過(guò)大部分的反爬機(jī)制,因?yàn)槟阊b得實(shí)在太像正常用戶;不過(guò)缺點(diǎn)也很明顯,就是慢。所以可以用requests搞定的優(yōu)先用requests,實(shí)在沒(méi)有辦法了再考慮模擬瀏覽器。

驗(yàn)證碼。驗(yàn)證碼一出就蛋疼了……Python有自動(dòng)識(shí)別圖像的包,不過(guò)對(duì)于大部分網(wǎng)站的驗(yàn)證碼都無(wú)能為力。寫一個(gè)自動(dòng)識(shí)別驗(yàn)證碼的程序理論上不是不行,但是這種復(fù)雜的機(jī)器學(xué)習(xí)項(xiàng)目一點(diǎn)都不比爬蟲系統(tǒng)本身難度低,從成本的角度考慮實(shí)在是得不償失——何況對(duì)于有些網(wǎng)站如谷歌,驗(yàn)證碼識(shí)別是非常困難的。所以對(duì)于驗(yàn)證碼問(wèn)題,首先是躲過(guò)去盡量不要觸發(fā)驗(yàn)證碼,實(shí)在觸發(fā)了只能乖乖人工去填驗(yàn)證碼。

各種各樣的反爬機(jī)制也算是因垂斯聽(tīng),只有身經(jīng)百戰(zhàn),爬得多了,才能談笑風(fēng)生,爬蟲水平不知道高到哪去了。有哪些有趣的反爬蟲手段?

爬蟲的道德節(jié)操和法律問(wèn)題

一些大型的網(wǎng)站都會(huì)有robot.txt,這算是與爬蟲者的一個(gè)協(xié)議。只要在robot.txt允許的范圍內(nèi)爬蟲就不存在道德和法律風(fēng)險(xiǎn),只不過(guò)實(shí)際上的爬蟲者一般都不看這個(gè)。

控制采集速度。過(guò)快的采集會(huì)對(duì)網(wǎng)站服務(wù)器造成不小的壓力,如果是性能差的小站可能就會(huì)被這么搞垮了。因此放慢采集速度相當(dāng)于各退一步,既給網(wǎng)站減輕壓力,也降低自己被封禁的風(fēng)險(xiǎn)。

爬蟲目前在法律上尚屬灰色地段,但爬別的網(wǎng)站用于自己的商業(yè)化用途也可能存在著法律風(fēng)險(xiǎn)。非法抓取使用“新浪微博”用戶信息 “脈脈”被判賠200萬(wàn)元,這是國(guó)內(nèi)的一條因爬蟲被判敗訴的新聞。所以各商業(yè)公司還是悠著點(diǎn),特別是爬較為隱私的數(shù)據(jù)。

責(zé)任編輯:龐桂玉 來(lái)源: 36大數(shù)據(jù)
相關(guān)推薦

2025-04-27 04:05:00

AI模型爬蟲

2019-01-07 05:51:34

AI人工智能高效流程

2016-01-29 20:23:23

華為

2009-04-09 09:32:00

VoWLANWLAN

2010-09-01 15:16:49

WLAN交換機(jī)結(jié)構(gòu)

2020-04-09 11:56:10

Elasticsear集群硬件

2021-04-22 13:38:21

前端開(kāi)發(fā)技術(shù)

2018-01-03 12:48:03

云計(jì)算云遷移網(wǎng)絡(luò)

2013-03-21 09:24:28

2015-10-10 13:49:23

2012-11-05 10:08:01

蘋果iCloud云應(yīng)用

2017-08-21 07:50:18

EasyStackOpenStack部署

2023-01-03 16:54:27

字節(jié)跳動(dòng)深度學(xué)習(xí)

2015-08-18 10:10:06

物聯(lián)網(wǎng)

2011-08-05 15:04:00

網(wǎng)絡(luò)攻擊黑客

2023-09-08 10:13:35

存儲(chǔ)EC系統(tǒng)

2021-05-12 09:15:48

Facebook 開(kāi)發(fā)技術(shù)

2019-03-26 14:42:10

委內(nèi)瑞拉斷電

2021-03-26 09:49:22

架構(gòu)并行處理

2023-02-21 10:58:01

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)