【數(shù)盟致力于成為最卓越的數(shù)據(jù)科學(xué)社區(qū),聚焦于大數(shù)據(jù)、分析挖掘、數(shù)據(jù)可視化領(lǐng)域,業(yè)務(wù)范圍:線下活動(dòng)、在線課程、獵頭服務(wù)、項(xiàng)目對(duì)接】 編者:本文來(lái)自攜程酒店研發(fā)部研發(fā)經(jīng)理崔廣宇在第三期【攜程技術(shù)微分享】上的分享,以下為整理的內(nèi)容概要。墻裂建議點(diǎn)擊視頻回放,“現(xiàn)場(chǎng)”圍觀段子手攻城獅大崔,如何高智商&高情商地完美碾壓爬蟲(chóng)。。。關(guān)注攜程技術(shù)中心微信公號(hào)ctriptech,可第一時(shí)間獲知微分享信息~ 你被爬蟲(chóng)侵?jǐn)_過(guò)么?當(dāng)你看到“爬蟲(chóng)”兩個(gè)字的時(shí)候,是不是已經(jīng)有點(diǎn)血脈賁張的感覺(jué)了?千萬(wàn)要忍耐,稍稍做點(diǎn)什么,就可以在名義上讓他們勝利,實(shí)際上讓他們受損失。 一、為什么要反爬蟲(chóng)1、爬蟲(chóng)占總PV比例較高,這樣浪費(fèi)錢(尤其是三月份爬蟲(chóng))。 三月份爬蟲(chóng)是個(gè)什么概念呢?每年的三月份我們會(huì)迎接一次爬蟲(chóng)高峰期。 最初我們百思不得其解。直到有一次,四月份的時(shí)候,我們刪除了一個(gè)url,然后有個(gè)爬蟲(chóng)不斷的爬取url,導(dǎo)致大量報(bào)錯(cuò),測(cè)試開(kāi)始找我們麻煩。我們只好特意為這個(gè)爬蟲(chóng)發(fā)布了一次站點(diǎn),把刪除的url又恢復(fù)回去了。 但是當(dāng)時(shí)我們的一個(gè)組員表示很不服,說(shuō),我們不能干掉爬蟲(chóng),也就罷了,還要專門為它發(fā)布,這實(shí)在是太沒(méi)面子了。于是出了個(gè)主意,說(shuō):url可以上,但是,絕對(duì)不給真實(shí)數(shù)據(jù)。 于是我們就把一個(gè)靜態(tài)文件發(fā)布上去了。報(bào)錯(cuò)停止了,爬蟲(chóng)沒(méi)有停止,也就是說(shuō)對(duì)方并不知道東西都是假的。這個(gè)事情給了我們一個(gè)很大的啟示,也直接成了我們反爬蟲(chóng)技術(shù)的核心:變更。 后來(lái)有個(gè)學(xué)生來(lái)申請(qǐng)實(shí)習(xí)。我們看了簡(jiǎn)歷發(fā)現(xiàn)她爬過(guò)攜程。后來(lái)面試的時(shí)候確認(rèn)了下,果然她就是四月份害我們發(fā)布的那個(gè)家伙。不過(guò)因?yàn)槭莻€(gè)妹子,技術(shù)也不錯(cuò),后來(lái)就被我們招安了。現(xiàn)在已經(jīng)快正式入職了。 后來(lái)我們一起討論的時(shí)候,她提到了,有大量的碩士在寫(xiě)論文的時(shí)候會(huì)選擇爬取OTA數(shù)據(jù),并進(jìn)行輿情分析。因?yàn)槲逶路萁徽撐模月?,大家都是讀過(guò)書(shū)的,你們懂的,前期各種DotA,LOL,到了三月份了,來(lái)不及了,趕緊抓數(shù)據(jù),四月份分析一下,五月份交論文。 就是這么個(gè)節(jié)奏。 2、公司可免費(fèi)查詢的資源被批量抓走,喪失競(jìng)爭(zhēng)力,這樣少賺錢。 OTA的價(jià)格可以在非登錄狀態(tài)下直接被查詢,這個(gè)是底線。如果強(qiáng)制登陸,那么可以通過(guò)封殺賬號(hào)的方式讓對(duì)方付出代價(jià),這也是很多網(wǎng)站的做法。但是我們不能強(qiáng)制對(duì)方登錄。那么如果沒(méi)有反爬蟲(chóng),對(duì)方就可以批量復(fù)制我們的信息,我們的競(jìng)爭(zhēng)力就會(huì)大大減少。 競(jìng)爭(zhēng)對(duì)手可以抓到我們的價(jià)格,時(shí)間長(zhǎng)了用戶就會(huì)知道,只需要去競(jìng)爭(zhēng)對(duì)手那里就可以了,沒(méi)必要來(lái)攜程。這對(duì)我們是不利的。 3、爬蟲(chóng)是否涉嫌違法? 如果是的話,是否可以起訴要求賠償?這樣可以賺錢。 這個(gè)問(wèn)題我特意咨詢了法務(wù),最后發(fā)現(xiàn)這在國(guó)內(nèi)還是個(gè)擦邊球,就是有可能可以起訴成功,也可能完全無(wú)效。所以還是需要用技術(shù)手段來(lái)做最后的保障。 二、反什么樣的爬蟲(chóng)1、十分低級(jí)的應(yīng)屆畢業(yè)生 開(kāi)頭我們提到的三月份爬蟲(chóng),就是一個(gè)十分明顯的例子。應(yīng)屆畢業(yè)生的爬蟲(chóng)通常簡(jiǎn)單粗暴,根本不管服務(wù)器壓力,加上人數(shù)不可預(yù)測(cè),很容易把站點(diǎn)弄掛。 順便說(shuō)下,通過(guò)爬攜程來(lái)獲取offer這條路已經(jīng)行不通了。因?yàn)槲覀兌贾溃谝粋€(gè)說(shuō)漂亮女人像花的人,是天才。而第二個(gè)。。。你們懂的吧? 2、十分低級(jí)的創(chuàng)業(yè)小公司 現(xiàn)在的創(chuàng)業(yè)公司越來(lái)越多,也不知道是被誰(shuí)忽悠的然后大家創(chuàng)業(yè)了發(fā)現(xiàn)不知道干什么好,覺(jué)得大數(shù)據(jù)比較熱,就開(kāi)始做大數(shù)據(jù)。 分析程序全寫(xiě)差不多了,發(fā)現(xiàn)自己手頭沒(méi)有數(shù)據(jù)。 怎么辦?寫(xiě)爬蟲(chóng)爬啊。于是就有了不計(jì)其數(shù)的小爬蟲(chóng),出于公司生死存亡的考慮,不斷爬取數(shù)據(jù)。 3、不小心寫(xiě)錯(cuò)了沒(méi)人去停止的失控小爬蟲(chóng) 攜程上的點(diǎn)評(píng)有的時(shí)候可能高達(dá)60%的訪問(wèn)量是爬蟲(chóng)。我們已經(jīng)選擇直接封鎖了,它們依然孜孜不倦地爬取。 什么意思呢?就是說(shuō),他們根本爬不到任何數(shù)據(jù),除了http code是200以外,一切都是不對(duì)的,可是爬蟲(chóng)依然不停止這個(gè)很可能就是一些托管在某些服務(wù)器上的小爬蟲(chóng),已經(jīng)無(wú)人認(rèn)領(lǐng)了,依然在辛勤地工作著。 4、成型的商業(yè)對(duì)手 這個(gè)是最大的對(duì)手,他們有技術(shù),有錢,要什么有什么,如果和你死磕,你就只能硬著頭皮和他死磕。 5、抽風(fēng)的搜索引擎 大家不要以為搜索引擎都是好人,他們也有抽風(fēng)的時(shí)候,而且一抽風(fēng)就會(huì)導(dǎo)致服務(wù)器性能下降,請(qǐng)求量跟網(wǎng)絡(luò)攻擊沒(méi)什么區(qū)別。 三、什么是爬蟲(chóng)和反爬蟲(chóng)因?yàn)榉磁老x(chóng)暫時(shí)是個(gè)較新的領(lǐng)域,因此有些定義要自己下。我們內(nèi)部定義是這樣的:
這里要切記,人力成本也是資源,而且比機(jī)器更重要。因?yàn)椋鶕?jù)摩爾定律,機(jī)器越來(lái)越便宜。而根據(jù)IT行業(yè)的發(fā)展趨勢(shì),程序員工資越來(lái)越貴。因此,讓對(duì)方加班才是王道,機(jī)器成本并不是特別值錢。 四、知己知彼:如何編寫(xiě)簡(jiǎn)單爬蟲(chóng)要想做反爬蟲(chóng),我們首先需要知道如何寫(xiě)個(gè)簡(jiǎn)單的爬蟲(chóng)。 目前網(wǎng)絡(luò)上搜索到的爬蟲(chóng)資料十分有限,通常都只是給一段python代碼。python是一門很好的語(yǔ)言,但是用來(lái)針對(duì)有反爬蟲(chóng)措施的站點(diǎn)做爬蟲(chóng),真的不是最優(yōu)選擇。 更諷刺的是,通常搜到的python爬蟲(chóng)代碼都會(huì)使用一個(gè)lynx的user-agent。你們應(yīng)該怎么處理這個(gè)user-agent,就不用我來(lái)說(shuō)了吧? 通常編寫(xiě)爬蟲(chóng)需要經(jīng)過(guò)這么幾個(gè)過(guò)程:
舉個(gè)例子,直接查看攜程生產(chǎn)url。在詳情頁(yè)點(diǎn)擊“確定”按鈕,會(huì)加載價(jià)格。假設(shè)價(jià)格是你想要的,那么抓出網(wǎng)絡(luò)請(qǐng)求之后,哪個(gè)請(qǐng)求才是你想要的結(jié)果呢? 答案出乎意料的簡(jiǎn)單,你只需要用根據(jù)網(wǎng)絡(luò)傳輸數(shù)據(jù)量進(jìn)行倒序排列即可。因?yàn)槠渌拿曰笮缘膗rl再多再?gòu)?fù)雜,開(kāi)發(fā)人員也不會(huì)舍得加數(shù)據(jù)量給他。 五、知己知彼:如何編寫(xiě)高級(jí)爬蟲(chóng)那么爬蟲(chóng)進(jìn)階應(yīng)該如何做呢?通常所謂的進(jìn)階有以下幾種: 分布式 通常會(huì)有一些教材告訴你,為了爬取效率,需要把爬蟲(chóng)分布式部署到多臺(tái)機(jī)器上。這完全是騙人的。分布式唯一的作用是:防止對(duì)方封IP。封IP是終極手段,效果非常好,當(dāng)然,誤傷起用戶也是非常爽的。 模擬JavaScript 有些教程會(huì)說(shuō),模擬javascript,抓取動(dòng)態(tài)網(wǎng)頁(yè),是進(jìn)階技巧。但是其實(shí)這只是個(gè)很簡(jiǎn)單的功能。因?yàn)?,如果?duì)方?jīng)]有反爬蟲(chóng),你完全可以直接抓ajax本身,而無(wú)需關(guān)心js怎么處理的。如果對(duì)方有反爬蟲(chóng),那么javascript必然十分復(fù)雜,重點(diǎn)在于分析,而不僅僅是簡(jiǎn)單的模擬。 換句話說(shuō):這應(yīng)該是基本功。 PhantomJs 這個(gè)是一個(gè)極端的例子。這個(gè)東西本意是用來(lái)做自動(dòng)測(cè)試的,結(jié)果因?yàn)樾Ч芎?,很多人拿?lái)做爬蟲(chóng)。但是這個(gè)東西有個(gè)硬傷,就是:效率。此外PhantomJs也是可以被抓到的,出于多方面原因,這里暫時(shí)不講?!?/p> 六、不同級(jí)別爬蟲(chóng)的優(yōu)缺點(diǎn)越是低級(jí)的爬蟲(chóng),越容易被封鎖,但是性能好,成本低。越是高級(jí)的爬蟲(chóng),越難被封鎖,但是性能低,成本也越高。 當(dāng)成本高到一定程度,我們就可以無(wú)需再對(duì)爬蟲(chóng)進(jìn)行封鎖。經(jīng)濟(jì)學(xué)上有個(gè)詞叫邊際效應(yīng)。付出成本高到一定程度,收益就不是很多了。 那么如果對(duì)雙方資源進(jìn)行對(duì)比,我們就會(huì)發(fā)現(xiàn),無(wú)條件跟對(duì)方死磕,是不劃算的。應(yīng)該有個(gè)黃金點(diǎn),超過(guò)這個(gè)點(diǎn),那就讓它爬好了。畢竟我們反爬蟲(chóng)不是為了面子,而是為了商業(yè)因素。 七、如何設(shè)計(jì)一個(gè)反爬蟲(chóng)系統(tǒng)(常規(guī)架構(gòu))有個(gè)朋友曾經(jīng)給過(guò)我這樣一個(gè)架構(gòu): 1、對(duì)請(qǐng)求進(jìn)行預(yù)處理,便于識(shí)別; 當(dāng)時(shí)我覺(jué)得,聽(tīng)起來(lái)似乎很有道理,不愧是架構(gòu),想法就是和我們不一樣。后來(lái)我們真正做起來(lái)反應(yīng)過(guò)來(lái)不對(duì)了。因?yàn)椋?/p> 如果能識(shí)別出爬蟲(chóng),哪還有那么多廢話?想怎么搞它就怎么搞它。如果識(shí)別不出來(lái)爬蟲(chóng),你對(duì)誰(shuí)做適當(dāng)處理? 三句話里面有兩句是廢話,只有一句有用的,而且還沒(méi)給出具體實(shí)施方式。那么:這種架構(gòu)(師)有什么用? 因?yàn)楫?dāng)前存在一個(gè)架構(gòu)師崇拜問(wèn)題,所以很多創(chuàng)業(yè)小公司以架構(gòu)師名義招開(kāi)發(fā)。給出的title都是:初級(jí)架構(gòu)師,架構(gòu)師本身就是個(gè)高級(jí)崗位,為什么會(huì)有初級(jí)架構(gòu)。這就相當(dāng)于:初級(jí)將軍/初級(jí)司令。 最后去了公司,發(fā)現(xiàn)十個(gè)人,一個(gè)CTO,九個(gè)架構(gòu)師,而且可能你自己是初級(jí)架構(gòu)師,其他人還是高級(jí)架構(gòu)師。不過(guò)初級(jí)架構(gòu)師還不算坑爹了,有些小創(chuàng)業(yè)公司還招CTO做開(kāi)發(fā)呢。 傳統(tǒng)反爬蟲(chóng)手段 1、后臺(tái)對(duì)訪問(wèn)進(jìn)行統(tǒng)計(jì),如果單個(gè)IP訪問(wèn)超過(guò)閾值,予以封鎖。 這個(gè)雖然效果還不錯(cuò),但是其實(shí)有兩個(gè)缺陷,一個(gè)是非常容易誤傷普通用戶,另一個(gè)就是,IP其實(shí)不值錢,幾十塊錢甚至有可能買到幾十萬(wàn)個(gè)IP。所以總體來(lái)說(shuō)是比較虧的。不過(guò)針對(duì)三月份呢爬蟲(chóng),這點(diǎn)還是非常有用的。 2、后臺(tái)對(duì)訪問(wèn)進(jìn)行統(tǒng)計(jì),如果單個(gè)session訪問(wèn)超過(guò)閾值,予以封鎖。 這個(gè)看起來(lái)更高級(jí)了一些,但是其實(shí)效果更差,因?yàn)閟ession完全不值錢,重新申請(qǐng)一個(gè)就可以了。 3、后臺(tái)對(duì)訪問(wèn)進(jìn)行統(tǒng)計(jì),如果單個(gè)userAgent訪問(wèn)超過(guò)閾值,予以封鎖。 這個(gè)是大招,類似于抗生素之類的,效果出奇的好,但是殺傷力過(guò)大,誤傷非常嚴(yán)重,使用的時(shí)候要非常小心。至今為止我們也就只短暫封殺過(guò)mac下的火狐。 4、以上的組合 組合起來(lái)能力變大,誤傷率下降,在遇到低級(jí)爬蟲(chóng)的時(shí)候,還是比較好用的。 由以上我們可以看出,其實(shí)爬蟲(chóng)反爬蟲(chóng)是個(gè)游戲,RMB玩家才最牛逼。因?yàn)樯厦嫣岬降姆椒ǎЧ话?,所以還是用JavaScript比較靠譜。 也許有人會(huì)說(shuō):javascript做的話,不是可以跳掉前端邏輯,直接拉服務(wù)嗎?怎么會(huì)靠譜呢?因?yàn)榘。沂且粋€(gè)標(biāo)題黨啊。JavaScript不僅僅是做前端。跳過(guò)前端不等于跳過(guò)JavaScript。也就是說(shuō):我們的服務(wù)器是nodejs做的。
eval eval已經(jīng)臭名昭著了,它效率低下,可讀性糟糕。正是我們所需要的。 goto js對(duì)goto支持并不好,因此需要自己實(shí)現(xiàn)goto。 混淆 目前的minify工具通常是minify成abcd之類簡(jiǎn)單的名字,這不符合我們的要求。我們可以minify成更好用的,比如阿拉伯語(yǔ)。為什么呢? 因?yàn)榘⒗Z(yǔ)有的時(shí)候是從左向右寫(xiě),有的時(shí)候是從右向左寫(xiě),還有的時(shí)候是從下向上寫(xiě)。除非對(duì)方雇個(gè)阿拉伯程序員,否則非頭疼死不可。 不穩(wěn)定代碼 什么bug不容易修?不容易重現(xiàn)的bug不好修。因此,我們的代碼要充滿不確定性,每次都不一樣。 代碼演示 下載代碼本身,可以更容易理解。這里簡(jiǎn)短介紹下思路:
到此為止。 前面我們提到了邊際效應(yīng),就是說(shuō),可以到此為止了。后續(xù)再投入人力就得不償失了。除非有專門的對(duì)手與你死磕。不過(guò)這個(gè)時(shí)候就是為了尊嚴(yán)而戰(zhàn),不是為了商業(yè)因素了。 瀏覽器檢測(cè) 針對(duì)不同的瀏覽器,我們的檢測(cè)方式是不一樣的。
八、我抓到你了——然后該怎么辦不會(huì)引發(fā)生產(chǎn)事件——直接攔截 可能引發(fā)生產(chǎn)事件——給假數(shù)據(jù)(也叫投毒) 此外還有一些發(fā)散性的思路。例如是不是可以在響應(yīng)里做SQL注入?畢竟是對(duì)方先動(dòng)的手。不過(guò)這個(gè)問(wèn)題法務(wù)沒(méi)有給具體回復(fù),也不容易和她解釋。因此暫時(shí)只是設(shè)想而已。 1、技術(shù)壓制 我們都知道,DotA AI里有個(gè)de命令,當(dāng)AI被擊殺后,它獲取經(jīng)驗(yàn)的倍數(shù)會(huì)提升。因此,前期殺AI太多,AI會(huì)一身神裝,無(wú)法擊殺。 正確的做法是,壓制對(duì)方等級(jí),但是不擊殺。反爬蟲(chóng)也是一樣的,不要一開(kāi)始就搞太過(guò)分,逼人家和你死磕。 2、心理戰(zhàn) 挑釁、憐憫、嘲諷、猥瑣。 以上略過(guò)不提,大家領(lǐng)會(huì)精神即可。 3、放水 這個(gè)可能是是最高境界了。 程序員都不容易,做爬蟲(chóng)的尤其不容易??蓱z可憐他們給他們一小口飯吃吧。沒(méi)準(zhǔn)過(guò)幾天你就因?yàn)榉磁老x(chóng)做得好,改行做爬蟲(chóng)了。 比如,前一陣子就有人找我問(wèn)我會(huì)不會(huì)做爬蟲(chóng)。。。。。我這么善良的人,能說(shuō)不會(huì)嗎???? |
|
來(lái)自: yanyahoo > 《大數(shù)據(jù)》