編者:本文來自攜程酒店研發部研發經理崔廣宇在第三期【攜程技術微分享】上的分享,如下爲整理的內容概要。牆裂建議點擊視頻回放,「現場」圍觀段子手攻城獅大崔,如何高智商&高情商地完美碾壓爬蟲。。。關注攜程技術中心微信公號ctriptech,可第一時間獲知微分享信息~javascript
你被爬蟲侵擾過麼?當你看到「爬蟲」兩個字的時候,是否是已經有點血脈賁張的感受了?千萬要忍耐,稍稍作點什麼,就能夠在名義上讓他們勝利,實際上讓他們受損失。html
一、爬蟲佔總PV比例較高,這樣浪費錢(尤爲是三月份爬蟲)。前端
三月份爬蟲是個什麼概念呢?每一年的三月份咱們會迎接一次爬蟲高峯期。java
最初咱們百思不得其解。直到有一次,四月份的時候,咱們刪除了一個url,而後有個爬蟲不斷的爬取url,致使大量報錯,測試開始找咱們麻煩。咱們只好特地爲這個爬蟲發佈了一次站點,把刪除的url又恢復回去了。node
可是當時咱們的一個組員表示很不服,說,咱們不能幹掉爬蟲,也就罷了,還要專門爲它發佈,這實在是太沒面子了。因而出了個主意,說:url能夠上,可是,絕對不給真實數據。python
因而咱們就把一個靜態文件發佈上去了。報錯中止了,爬蟲沒有中止,也就是說對方並不知道東西都是假的。這個事情給了咱們一個很大的啓示,也直接成了咱們反爬蟲技術的核心:變動。程序員
後來有個學生來申請實習。咱們看了簡歷發現她爬過攜程。後來面試的時候確認了下,果真她就是四月份害咱們發佈的那個傢伙。不過由於是個妹子,技術也不錯,後來就被咱們招安了。如今已經快正式入職了。面試
後來咱們一塊兒討論的時候,她提到了,有大量的碩士在寫論文的時候會選擇爬取OTA數據,並進行輿情分析。由於五月份交論文,因此嘛,你們都是讀過書的,大家懂的 到了三月份抓數據,四月份分析,五月份交論文。ajax
就是這麼個節奏。瀏覽器
二、公司可免費查詢的資源被批量抓走,喪失競爭力,這樣少賺錢。
OTA的價格能夠在非登陸狀態下直接被查詢,這個是底線。若是強制登錄,那麼能夠經過封殺帳號的方式讓對方付出代價,這也是不少網站的作法。可是咱們不能強制對方登陸。那麼若是沒有反爬蟲,對方就能夠批量複製咱們的信息,咱們的競爭力就會大大減小。
競爭對手能夠抓到咱們的價格,時間長了用戶就會知道,只須要去競爭對手那裏就能夠了,不必來攜程。這對咱們是不利的。
三、爬蟲是否涉嫌違法? 若是是的話,是否能夠起訴要求賠償?這樣能夠賺錢。
這個問題我特地諮詢了法務,最後發現這在國內仍是個擦邊球,就是有可能能夠起訴成功,也可能徹底無效。因此仍是須要用技術手段來作最後的保障。
一、十分低級的應屆畢業生
開頭咱們提到的三月份爬蟲,就是一個十分明顯的例子。應屆畢業生的爬蟲一般簡單粗暴,根本無論服務器壓力,加上人數不可預測,很容易把站點弄掛。
順便說下,經過爬攜程來獲取offer這條路已經行不通了。由於咱們都知道,第一個說漂亮女人像花的人,是天才。而第二個。。。大家懂的吧?
二、十分低級的創業小公司
如今的創業公司愈來愈多,也不知道是被誰忽悠的而後你們創業了發現不知道幹什麼好,以爲大數據比較熱,就開始作大數據。
分析程序全寫差很少了,發現本身手頭沒有數據。
怎麼辦?寫爬蟲爬啊。因而就有了不可勝數的小爬蟲,出於公司生死存亡的考慮,不斷爬取數據。
三、不當心寫錯了沒人去中止的失控小爬蟲
攜程上的點評有的時候可能高達60%的訪問量是爬蟲。咱們已經選擇直接封鎖了,它們依然孜孜不倦地爬取。
什麼意思呢?就是說,他們根本爬不到任何數據,除了http code是200之外,一切都是不對的,但是爬蟲依然不中止這個極可能就是一些託管在某些服務器上的小爬蟲,已經無人認領了,依然在辛勤地工做着。
四、成型的商業對手
這個是最大的對手,他們有技術,有錢,要什麼有什麼,若是和你死磕,你就只能硬着頭皮和他死磕。
五、抽風的搜索引擎
你們不要覺得搜索引擎都是好人,他們也有抽風的時候,並且一抽風就會致使服務器性能降低,請求量跟網絡攻擊沒什麼區別。
由於反爬蟲暫時是個較新的領域,所以有些定義要本身下。咱們內部定義是這樣的:
爬蟲:使用任何技術手段,批量獲取網站信息的一種方式。關鍵在於批量。
反爬蟲:使用任何技術手段,阻止別人批量獲取本身網站信息的一種方式。關鍵也在於批量。
誤傷:在反爬蟲的過程當中,錯誤的將普通用戶識別爲爬蟲。誤傷率高的反爬蟲策略,效果再好也不能用。
攔截:成功地阻止爬蟲訪問。這裏會有攔截率的概念。一般來講,攔截率越高的反爬蟲策略,誤傷的可能性就越高。所以須要作個權衡。
資源:機器成本與人力成本的總和。
這裏要切記,人力成本也是資源,並且比機器更重要。由於,根據摩爾定律,機器愈來愈便宜。而根據IT行業的發展趨勢,程序員工資愈來愈貴。所以,讓對方加班纔是王道,機器成本並非特別值錢。
要想作反爬蟲,咱們首先須要知道如何寫個簡單的爬蟲。
目前網絡上搜索到的爬蟲資料十分有限,一般都只是給一段python代碼。python是一門很好的語言,可是用來針對有反爬蟲措施的站點作爬蟲,真的不是最優選擇。
更諷刺的是,一般搜到的python爬蟲代碼都會使用一個lynx的user-agent。大家應該怎麼處理這個user-agent,就不用我來講了吧?
一般編寫爬蟲須要通過這麼幾個過程:
分析頁面請求格式
建立合適的http請求
批量發送http請求,獲取數據
舉個例子,直接查看攜程生產url。在詳情頁點擊「肯定」按鈕,會加載價格。假設價格是你想要的,那麼抓出網絡請求以後,哪一個請求才是你想要的結果呢?
答案出乎意料的簡單,你只須要用根據網絡傳輸數據量進行倒序排列便可。由於其餘的迷惑性的url再多再複雜,開發人員也不會捨得加數據量給他。
那麼爬蟲進階應該如何作呢?一般所謂的進階有如下幾種:
分佈式
一般會有一些教材告訴你,爲了爬取效率,須要把爬蟲分佈式部署到多臺機器上。這徹底是騙人的。分佈式惟一的做用是:防止對方封IP。封IP是終極手段,效果很是好,固然,誤傷起用戶也是很是爽的。
模擬JavaScript
有些教程會說,模擬javascript,抓取動態網頁,是進階技巧。可是其實這只是個很簡單的功能。由於,若是對方沒有反爬蟲,你徹底能夠直接抓ajax自己,而無需關心js怎麼處理的。若是對方有反爬蟲,那麼javascript必然十分複雜,重點在於分析,而不只僅是簡單的模擬。
換句話說:這應該是基本功。
PhantomJs
這個是一個極端的例子。這個東西本意是用來作自動測試的,結果由於效果很好,不少人拿來作爬蟲。可是這個東西有個硬傷,就是:效率。此外PhantomJs也是能夠被抓到的,出於多方面緣由,這裏暫時不講。
越是低級的爬蟲,越容易被封鎖,可是性能好,成本低。越是高級的爬蟲,越難被封鎖,可是性能低,成本也越高。
當成本高到必定程度,咱們就能夠無需再對爬蟲進行封鎖。經濟學上有個詞叫邊際效應。付出成本高到必定程度,收益就不是不少了。
那麼若是對雙方資源進行對比,咱們就會發現,無條件跟對方死磕,是不划算的。應該有個黃金點,超過這個點,那就讓它爬好了。畢竟咱們反爬蟲不是爲了面子,而是爲了商業因素。
有個朋友曾經給過我這樣一個架構:
一、對請求進行預處理,便於識別;
二、識別是不是爬蟲;
三、針對識別結果,進行適當的處理;
當時我以爲,聽起來彷佛頗有道理,不愧是架構,想法就是和咱們不同。後來咱們真正作起來反應過來不對了。由於:
若是能識別出爬蟲,哪還有那麼多廢話?想怎麼搞它就怎麼搞它。若是識別不出來爬蟲,你對誰作適當處理?
三句話裏面有兩句是廢話,只有一句有用的,並且還沒給出具體實施方式。那麼:這種架構(師)有什麼用?
由於當前存在一個架構師崇拜問題,因此不少創業小公司以架構師名義招開發。給出的title都是:初級架構師,架構師自己就是個高級崗位,爲何會有初級架構。這就至關於:初級將軍/初級司令。
最後去了公司,發現十我的,一個CTO,九個架構師,並且可能你本身是初級架構師,其餘人仍是高級架構師。不過初級架構師還不算坑爹了,有些小創業公司還招CTO作開發呢。
傳統反爬蟲手段
一、後臺對訪問進行統計,若是單個IP訪問超過閾值,予以封鎖。
這個雖然效果還不錯,可是其實有兩個缺陷,一個是很是容易誤傷普通用戶,另外一個就是,IP其實不值錢,幾十塊錢甚至有可能買到幾十萬個IP。因此整體來講是比較虧的。不過針對三月份呢爬蟲,這點仍是很是有用的。
二、後臺對訪問進行統計,若是單個session訪問超過閾值,予以封鎖。
這個看起來更高級了一些,可是其實效果更差,由於session徹底不值錢,從新申請一個就能夠了。
三、後臺對訪問進行統計,若是單個userAgent訪問超過閾值,予以封鎖。
這個是大招,相似於抗生素之類的,效果出奇的好,可是殺傷力過大,誤傷很是嚴重,使用的時候要很是當心。至今爲止咱們也就只短暫封殺過mac下的火狐。
四、以上的組合
組合起來能力變大,誤傷率降低,在遇到低級爬蟲的時候,仍是比較好用的。
由以上咱們能夠看出,其實爬蟲反爬蟲是個遊戲,RMB玩家才最牛逼。由於上面提到的方法,效果均通常,因此仍是用JavaScript比較靠譜。
也許有人會說:javascript作的話,不是能夠跳掉前端邏輯,直接拉服務嗎?怎麼會靠譜呢?由於啊,我是一個標題黨啊。JavaScript不只僅是作前端。跳過前端不等於跳過JavaScript。也就是說:咱們的服務器是nodejs作的。
思考題:咱們寫代碼的時候,最怕碰到什麼代碼?什麼代碼很差調試?
eval
eval已經臭名昭著了,它效率低下,可讀性糟糕。正是咱們所須要的。
goto
js對goto支持並很差,所以須要本身實現goto。
混淆
目前的minify工具一般是minify成abcd之類簡單的名字,這不符合咱們的要求。咱們能夠minify成更好用的,好比阿拉伯語。爲何呢? 由於阿拉伯語有的時候是從左向右寫,有的時候是從右向左寫,還有的時候是從下向上寫。除非對方僱個阿拉伯程序員,不然非頭疼死不可。
不穩定代碼
什麼bug不容易修?不容易重現的bug很差修。所以,咱們的代碼要充滿不肯定性,每次都不同。
代碼演示
下載代碼自己,能夠更容易理解。這裏簡短介紹下思路:
純JAVASCRIPT反爬蟲DEMO,經過更改鏈接地址,來讓對方抓取到錯誤價格。這種方法簡單,可是若是對方針對性的來查看,十分容易被發現。
純JAVASCRIPT反爬蟲DEMO,更改key。這種作法簡單,不容易被發現。可是能夠經過有意爬取錯誤價格的方式來實現。
純JAVASCRIPT反爬蟲DEMO,更改動態key。這種方法可讓更改key的代價變爲0,所以代價更低。
純JAVASCRIPT反爬蟲DEMO,十分複雜的更改key。這種方法,可讓對方很難分析,若是加了後續提到的瀏覽器檢測,更難被爬取。
到此爲止。
前面咱們提到了邊際效應,就是說,能夠到此爲止了。後續再投入人力就得不償失了。除非有專門的對手與你死磕。不過這個時候就是爲了尊嚴而戰,不是爲了商業因素了。
瀏覽器檢測
針對不一樣的瀏覽器,咱們的檢測方式是不同的。
IE 檢測bug;
FF 檢測對標準的嚴格程度;
Chrome 檢測強大特性。
不會引起生產事件——直接攔截
可能引起生產事件——給假數據(也叫投毒)
此外還有一些發散性的思路。例如是否是能夠在響應裏作SQL注入?畢竟是對方先動的手。不過這個問題法務沒有給具體回覆,也不容易和她解釋。所以暫時只是設想而已。
一、技術壓制
咱們都知道,DotA AI裏有個de命令,當AI被擊殺後,它獲取經驗的倍數會提高。所以,前期殺AI太多,AI會一身神裝,沒法擊殺。
正確的作法是,壓制對方等級,可是不擊殺。反爬蟲也是同樣的,不要一開始就搞太過度,逼人家和你死磕。
二、心理戰
挑釁、憐憫、嘲諷、猥瑣。
以上略過不提,你們領會精神便可。
三、放水
這個多是是最高境界了。
程序員都不容易,作爬蟲的尤爲不容易。可憐可憐他們給他們一小口飯吃吧。沒準過幾天你就由於反爬蟲作得好,改行作爬蟲了。
好比,前一陣子就有人找我問我會不會作爬蟲。。。。。我這麼善良的人,能說不會嗎????