有哪些有趣的反爬蟲手段?
爬蟲與反爬蟲的鬥爭從未停止。
反爬蟲程序員一直在與爬蟲程序員做鬥爭~
那麼,大家都見過什麼有趣的反爬蟲手段呢?
或者從反爬蟲的角度來想,怎樣的手段才能增加爬蟲的難度呢?
說一個關於網易雲音樂的把
對付一些小白是可以的,因為他們主體頁面是非同步載入嵌套在iframe裡面的,並且 src="about:blank"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~割
看了@ peng yang 兄弟的問題,說一下去哪兒的該怎麼爬
- 選擇去哪兒的m站去哪兒網--聰明你的旅行
- 同樣的操作,然後你會發現一個問題,就是頁面展示的數字和html文件里的數字不一致
1240的價格在html里竟然是4230
- 根據css你會發現他們用了一個字體,打開你就發現了一件事
正常字體是0123456789,在去哪兒官方的字體里被替換成了圖片里的
然後你根據這個做一些對應解析,就可以爬出正確的數據了。
PS:PC端就算了
~~~~~~~~~~~~~
現在很多頁面的內容都是採用ajax非同步載入進來的,所以可以研究一下框架selenium,網易雲音樂和去哪兒都可以利用這個框架爬取數據
類似的還有攜程的數據,但是攜程的PC端的命中率沒有m站高。
遇到過的:
1、根據一定行為特徵,封IP或者彈驗證碼。
2、蜜罐,確認是爬蟲之後,返回虛假數據。這套玩法,厚顏無恥得說,在線下我算是先行者。當年汽車大V@王洪浩 和我一個宿舍,老是偷偷把公用電腦上我的作業拷走去交差(那個時候的學生窮呀,只能一個宿舍五六個人公用一台電腦)。於是有一次,我把作業裡面一大段的實驗報告換成了一段咿咿呀呀的小黃文,然後讓他拷走了。
3、亂碼。關鍵信息不是正常字元,而是通過圖片或者亂碼來展示(通過渲染讓亂碼成為可閱讀的正常字元)。
最最牛的還是IT桔子,當判別出爬蟲之後會返回「F**k you! Spider」,徹底被IT桔子丁丁的尺寸震撼了。
…更多文章請到數據冰山 - 知乎專欄
…更多回答請看何明科的主頁
反爬蟲手段在我看來,概括起來無非只有兩種,一種是從客戶端的角度進行反爬。一種是從服務端進行反爬。下面是一些我見過和思考的方法。
從客戶端的角度進行反爬蟲的話,常見的比如微博、QQ空間等複雜登陸流程和ajax動態載入,無疑會讓爬蟲工程師的工作量增加不少。我說說比這個更困難的。具體說來,巨難模式的大概是這樣。一是動態生成url,主要是動態生成構成該url的key。你說這有啥難度,我js功底,數學功底都很好,我通過抓包和閱讀頁面的js源碼,分析它生成key的方式不就行了?是這樣的,沒錯。如果目標站點給出的js代碼經過了混淆怎麼辦?你說,省事兒點我可以用自動化的方式打開瀏覽器來生成url啊。嗯,這個也可行。但是如果對方提取不同瀏覽器的特徵,直接根據這個來判定你到底是webdriver打開的瀏覽器或者真實用戶打開的瀏覽器,又怎麼辦?這。。。。這時你通過分析點擊事件,在瀏覽器中逐步調試js,一步一步逆向分析,這個過程會十分艱苦(別問我為什麼?我踏馬遇到過啊!)終於找到了key的生成方式,這時候再去請求頁面似乎沒問題了。這場較量你以微弱的優勢獲勝。
從伺服器的角度進行反爬蟲的話,我把它歸為兩類。一類是實時反爬蟲方式,另外一種是非實時反爬蟲方式。先說說非實時的反爬蟲方式吧。大家寫爬蟲的都心知肚明,我想要的數據就是xx頁面的xx信息,我又不需要JS、CSS和Images這些元素,這不是浪費我的資源、拖慢我的信息偷取速度嗎?在Nginx等Web Server中我們可以拿到所有IP的訪問記錄,我們也可以拿到頁面嵌入的JS統計流量的數據,基於這兩點可以拿流量統計記錄的IP和伺服器日誌記錄的IP進行比較,如果伺服器日誌裡面某個IP發起了大量請求,但是流量統計里根本找不到,或者訪問量只有很少幾個,那麼來源於該IP的請求是爬蟲無疑。再說說實時的反爬蟲方式吧。實時的反爬蟲方式可以直接通過request headers頭信息阻擋一些簡單小爬蟲,但是對於經驗豐富、設計優良的爬蟲是無效的。這時候更通用的一般是採用滑動時間窗口驗證。在你以為好不容易繞過了客戶端,想著可以痛痛快快的爬取目標站點的時候,發現自己IP被封了。這根本不是事兒啊,你說,我還可以直接在網上找免費的代理IP啊,代理IP這麼多,還免費呢,可用的總不少吧。於是你加班寫了一個爬各大代理IP的網站的爬蟲,然後拿來爬目標站點,結果還是被ban了,what the fuck!不可能啊,代理IP都會被封?難道代理沒效果?我用的都是高匿的啊。哦,你突然想明白了,踏馬免費的代理IP,別人也在用啊。萬一別人早就爬了目標網站,頻率沒控制好而被封了呢?還踏馬更糟的情況就是,萬一目標網站的反爬蟲工程師閑著蛋疼,踏馬自己也寫了一個腳本爬公開的代理IP呢,然後直接把這些IP拉黑了呢?額,免費代理IP這條路你沒走通(付費代理IP的質量也不見得高啊! 掩面哭.jpg)。於是你想了想,那我動態撥號呢?動態撥號這方法不錯啊,每隔一段時間就重新撥號,獲取新的高質量IP,這樣目標站點就沒辦法封你了。沒過多久,你發現你的賬號被封了。於是,你不得不放慢數據採集的頻率,去摸索目標站點的最大容忍程度。在把大致的邊緣摸清了過後,你又購買了一批賬號,使用分散式的方式進行內容盜取(原諒我使用這個詞,有時候自己使用爬蟲爬別家數據的時候,感覺自己就是一個小偷啊)。結果你發現成本也越來越高了,無論是付出的研發成本還是物質上的成本。
當反爬蟲成本高到一定程度了(相應的爬蟲成本會更高),目標站點無需再對你進行封鎖了。再說了,大家都是程序員,都挺不容易的,難道反爬蟲工程師連一口飯都不留給爬蟲工程師嗎?
以上說的基本都是判定爬蟲的過程,而非發現爬蟲的後續處理,我個人覺得既然是反爬蟲,最重要的還是怎麼判定爬蟲(不過我看很多答主都答的是判定是爬蟲過後的處理方式)。你說,你要是都知道對方是爬蟲,想搞點事兒出來,不是很容易的嗎?比如技術手段上的sql注入啊、蜜罐啊、心理上的響應內容「fuck you」之類的啊、還有投毒這種玩陰的啊、或者直接拒絕響應/彈出複雜驗證碼啊,不都輕輕鬆鬆了嗎?
另外,我也順帶說一句,玩爬蟲的童鞋還是應該有點爬蟲工程師的基本素養,人家知乎不也允許你爬取嗎(可以看看他的robots協議 https://www.zhihu.com/robots.txt ,不過基本上爬蟲都不會遵循robots協議,該怎麼爬還是怎麼爬 , 爬蟲工程師表示混口飯吃我也很無奈啊), 別動不動就多線程加上非同步IO,鼓吹自己數據採集得多快,速度太快了容易給目標網站造成壓力,特別是小型網站。另外一點,爬太快你的爬蟲也很容易被封殺,所以適當的請求間隔對爬蟲和對目標網站都有好處!
去哪兒網的航班查詢,價格像拼圖orz...
電商網站給假商品假價格都是公開的秘密了……
當然是只有爬蟲可見的……
通常發現爬蟲又不想被爬的時候,很多網站會選擇拒絕請求,但也有很多網站會投毒,上面說的電商網站的策略就是一種經典的投毒手段。
更簡單一點兒的還有給404欺騙爬蟲這個頁面不存在,給無窮跳轉玩死爬蟲等等……
當然這個事情應該說還是爬蟲先動手的……畢竟爬蟲經常騙網站自己是Chrome、Firefox什麼的。為了避免被投毒,現在爬蟲也有冒充自己是百度或者谷歌的蜘蛛的……
從鏈接發現下手可以搞一些正常的url pattern 的頁面 鏈接做成隱藏鏈接 正常用戶看不到(比如白底白字,或者被遮蓋) 但是大部分爬蟲就爬進去了 然後就對這些ip做懲罰就行了比如www.xxx.com?id=12345 大部分id參數是正常頁面 把一些id做成只有隱藏鏈接的假id 監控這些頁面被訪問的ip 然後收割吧 基本都是爬蟲
轉一篇崔廣宇老師16年的分享,儘管整個分享過程中並沒有太多奇技淫巧,但是對於反爬蟲的「道」,闡述及其清晰。因為爬蟲和反爬蟲的鬥智斗勇,學道顯然要比學術更好。
原文在這裡:關於反爬蟲,看這一篇就夠了
你被爬蟲侵擾過么?當你看到「爬蟲」兩個字的時候,是不是已經有點血脈賁張的感覺了?千萬要忍耐,稍稍做點什麼,就可以在名義上讓他們勝利,實際上讓他們受損失。
一、為什麼要反爬蟲
1、爬蟲佔總PV比例較高,這樣浪費錢(尤其是三月份爬蟲)。
三月份爬蟲是個什麼概念呢?每年的三月份我們會迎接一次爬蟲高峰期。
最初我們百思不得其解。直到有一次,四月份的時候,我們刪除了一個url,然後有個爬蟲不斷的爬取url,導致大量報錯,測試開始找我們麻煩。我們只好特意為這個爬蟲發布了一次站點,把刪除的url又恢復回去了。
但是當時我們的一個組員表示很不服,說,我們不能幹掉爬蟲,也就罷了,還要專門為它發布,這實在是太沒面子了。於是出了個主意,說:url可以上,但是,絕對不給真實數據。
於是我們就把一個靜態文件發布上去了。報錯停止了,爬蟲沒有停止,也就是說對方並不知道東西都是假的。這個事情給了我們一個很大的啟示,也直接成了我們反爬蟲技術的核心:變更。
後來有個學生來申請實習。我們看了簡歷發現她爬過攜程。後來面試的時候確認了下,果然她就是四月份害我們發布的那個傢伙。不過因為是個妹子,技術也不錯,後來就被我們招安了。現在已經快正式入職了。
後來我們一起討論的時候,她提到了,有大量的碩士在寫論文的時候會選擇爬取OTA數據,並進行輿情分析。因為五月份交論文,所以嘛,大家都是讀過書的,你們懂的,前期各種DotA,LOL,到了三月份了,來不及了,趕緊抓數據,四月份分析一下,五月份交論文。
就是這麼個節奏。
2、公司可免費查詢的資源被批量抓走,喪失競爭力,這樣少賺錢。
OTA的價格可以在非登錄狀態下直接被查詢,這個是底線。如果強制登陸,那麼可以通過封殺賬號的方式讓對方付出代價,這也是很多網站的做法。但是我們不能強制對方登錄。那麼如果沒有反爬蟲,對方就可以批量複製我們的信息,我們的競爭力就會大大減少。
競爭對手可以抓到我們的價格,時間長了用戶就會知道,只需要去競爭對手那裡就可以了,沒必要來攜程。這對我們是不利的。
3、爬蟲是否涉嫌違法? 如果是的話,是否可以起訴要求賠償?這樣可以賺錢。
這個問題我特意諮詢了法務,最後發現這在國內還是個擦邊球,就是有可能可以起訴成功,也可能完全無效。所以還是需要用技術手段來做最後的保障。
二、反什麼樣的爬蟲
1、十分低級的應屆畢業生
開頭我們提到的三月份爬蟲,就是一個十分明顯的例子。應屆畢業生的爬蟲通常簡單粗暴,根本不管伺服器壓力,加上人數不可預測,很容易把站點弄掛。
順便說下,通過爬攜程來獲取offer這條路已經行不通了。因為我們都知道,第一個說漂亮女人像花的人,是天才。而第二個。。。你們懂的吧?
2、十分低級的創業小公司
現在的創業公司越來越多,也不知道是被誰忽悠的然後大家創業了發現不知道幹什麼好,覺得大數據比較熱,就開始做大數據。
分析程序全寫差不多了,發現自己手頭沒有數據。
怎麼辦?寫爬蟲爬啊。於是就有了不計其數的小爬蟲,出於公司生死存亡的考慮,不斷爬取數據。
3、不小心寫錯了沒人去停止的失控小爬蟲
攜程上的點評有的時候可能高達60%的訪問量是爬蟲。我們已經選擇直接封鎖了,它們依然孜孜不倦地爬取。
什麼意思呢?就是說,他們根本爬不到任何數據,除了http code是200以外,一切都是不對的,可是爬蟲依然不停止這個很可能就是一些託管在某些伺服器上的小爬蟲,已經無人認領了,依然在辛勤地工作著。
4、成型的商業對手
這個是最大的對手,他們有技術,有錢,要什麼有什麼,如果和你死磕,你就只能硬著頭皮和他死磕。
5、抽風的搜索引擎
大家不要以為搜索引擎都是好人,他們也有抽風的時候,而且一抽風就會導致伺服器性能下降,請求量跟網路攻擊沒什麼區別。
三、什麼是爬蟲和反爬蟲
因為反爬蟲暫時是個較新的領域,因此有些定義要自己下。我們內部定義是這樣的:
- 爬蟲:使用任何技術手段,批量獲取網站信息的一種方式。關鍵在於批量。
- 反爬蟲:使用任何技術手段,阻止別人批量獲取自己網站信息的一種方式。關鍵也在於批量。
- 誤傷:在反爬蟲的過程中,錯誤的將普通用戶識別為爬蟲。誤傷率高的反爬蟲策略,效果再好也不能用。
- 攔截:成功地阻止爬蟲訪問。這裡會有攔截率的概念。通常來說,攔截率越高的反爬蟲策略,誤傷的可能性就越高。因此需要做個權衡。
- 資源:機器成本與人力成本的總和。
這裡要切記,人力成本也是資源,而且比機器更重要。因為,根據摩爾定律,機器越來越便宜。而根據IT行業的發展趨勢,程序員工資越來越貴。因此,讓對方加班才是王道,機器成本並不是特別值錢。
四、知己知彼:如何編寫簡單爬蟲
要想做反爬蟲,我們首先需要知道如何寫個簡單的爬蟲。
目前網路上搜索到的爬蟲資料十分有限,通常都只是給一段python代碼。python是一門很好的語言,但是用來針對有反爬蟲措施的站點做爬蟲,真的不是最優選擇。
更諷刺的是,通常搜到的python爬蟲代碼都會使用一個lynx的user-agent。你們應該怎麼處理這個user-agent,就不用我來說了吧?
通常編寫爬蟲需要經過這麼幾個過程:
- 分析頁面請求格式
- 創建合適的http請求
- 批量發送http請求,獲取數據
舉個例子,直接查看攜程生產url。在詳情頁點擊「確定」按鈕,會載入價格。假設價格是你想要的,那麼抓出網路請求之後,哪個請求才是你想要的結果呢?
答案出乎意料的簡單,你只需要用根據網路傳輸數據量進行倒序排列即可。因為其他的迷惑性的url再多再複雜,開發人員也不會捨得加數據量給他。
五、知己知彼:如何編寫高級爬蟲
那麼爬蟲進階應該如何做呢?通常所謂的進階有以下幾種:
分散式
通常會有一些教材告訴你,為了爬取效率,需要把爬蟲分散式部署到多台機器上。這完全是騙人的。分散式唯一的作用是:防止對方封IP。封IP是終極手段,效果非常好,當然,誤傷起用戶也是非常爽的。
模擬JavaScript
有些教程會說,模擬javascript,抓取動態網頁,是進階技巧。但是其實這只是個很簡單的功能。因為,如果對方沒有反爬蟲,你完全可以直接抓ajax本身,而無需關心js怎麼處理的。如果對方有反爬蟲,那麼javascript必然十分複雜,重點在於分析,而不僅僅是簡單的模擬。
換句話說:這應該是基本功。
PhantomJs
這個是一個極端的例子。這個東西本意是用來做自動測試的,結果因為效果很好,很多人拿來做爬蟲。但是這個東西有個硬傷,就是:效率。此外PhantomJs也是可以被抓到的,出於多方面原因,這裡暫時不講。
六、不同級別爬蟲的優缺點
越是低級的爬蟲,越容易被封鎖,但是性能好,成本低。越是高級的爬蟲,越難被封鎖,但是性能低,成本也越高。
當成本高到一定程度,我們就可以無需再對爬蟲進行封鎖。經濟學上有個詞叫邊際效應。付出成本高到一定程度,收益就不是很多了。
那麼如果對雙方資源進行對比,我們就會發現,無條件跟對方死磕,是不划算的。應該有個黃金點,超過這個點,那就讓它爬好了。畢竟我們反爬蟲不是為了面子,而是為了商業因素。
七、如何設計一個反爬蟲系統(常規架構)
有個朋友曾經給過我這樣一個架構:
1、對請求進行預處理,便於識別;
2、識別是否是爬蟲;3、針對識別結果,進行適當的處理;當時我覺得,聽起來似乎很有道理,不愧是架構,想法就是和我們不一樣。後來我們真正做起來反應過來不對了。因為:
如果能識別出爬蟲,哪還有那麼多廢話?想怎麼搞它就怎麼搞它。如果識別不出來爬蟲,你對誰做適當處理?
三句話裡面有兩句是廢話,只有一句有用的,而且還沒給出具體實施方式。那麼:這種架構(師)有什麼用?
因為當前存在一個架構師崇拜問題,所以很多創業小公司以架構師名義招開發。給出的title都是:初級架構師,架構師本身就是個高級崗位,為什麼會有初級架構。這就相當於:初級將軍/初級司令。
最後去了公司,發現十個人,一個CTO,九個架構師,而且可能你自己是初級架構師,其他人還是高級架構師。不過初級架構師還不算坑爹了,有些小創業公司還招CTO做開發呢。
傳統反爬蟲手段
1、後台對訪問進行統計,如果單個IP訪問超過閾值,予以封鎖。
這個雖然效果還不錯,但是其實有兩個缺陷,一個是非常容易誤傷普通用戶,另一個就是,IP其實不值錢,幾十塊錢甚至有可能買到幾十萬個IP。所以總體來說是比較虧的。不過針對三月份呢爬蟲,這點還是非常有用的。
2、後台對訪問進行統計,如果單個session訪問超過閾值,予以封鎖。
這個看起來更高級了一些,但是其實效果更差,因為session完全不值錢,重新申請一個就可以了。
3、後台對訪問進行統計,如果單個userAgent訪問超過閾值,予以封鎖。
這個是大招,類似於抗生素之類的,效果出奇的好,但是殺傷力過大,誤傷非常嚴重,使用的時候要非常小心。至今為止我們也就只短暫封殺過mac下的火狐。
4、以上的組合
組合起來能力變大,誤傷率下降,在遇到低級爬蟲的時候,還是比較好用的。
由以上我們可以看出,其實爬蟲反爬蟲是個遊戲,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注入?畢竟是對方先動的手。不過這個問題法務沒有給具體回復,也不容易和她解釋。因此暫時只是設想而已。
1、技術壓制
我們都知道,DotA AI里有個de命令,當AI被擊殺後,它獲取經驗的倍數會提升。因此,前期殺AI太多,AI會一身神裝,無法擊殺。
正確的做法是,壓制對方等級,但是不擊殺。反爬蟲也是一樣的,不要一開始就搞太過分,逼人家和你死磕。
2、心理戰
挑釁、憐憫、嘲諷、猥瑣。
以上略過不提,大家領會精神即可。
3、放水
這個可能是是最高境界了。
程序員都不容易,做爬蟲的尤其不容易。可憐可憐他們給他們一小口飯吃吧。沒準過幾天你就因為反爬蟲做得好,改行做爬蟲了。
比如,前一陣子就有人找我問我會不會做爬蟲。。。。。我這麼善良的人,能說不會嗎????
你想更深入了解學習Python知識體系,你可以看一下我們花費了一個多月整理了上百小時的幾百個知識點體系內容:
【超全整理】《Python自動化全能開發從入門到精通》筆記全放送
打個球回來發現輪子哥點贊了haha
既然大家對微博爬蟲這麼感興趣,我就再加一條
新浪的另一個反爬蟲機制 訪客系統 Sina Visitor System
如果不帶cookie訪問微博的頁面的話,並不會返回正常的頁面而是返回一個「訪客系統」頁面
知乎的爬蟲也會有這樣的問題Sina Visitor System
但是百度的就不會
所以直接設置header
User-Agent:baiduspider
哦了
這裡再放上之前的寫的一個簡單的微博關係爬蟲
知乎專欄:基於JAVA的新浪微博關係網路爬蟲 - 知乎專欄
Github:pokerfaceSad/SinaNetSpider
-----------------------以下是原回答----------------
前段時間爬微博,用小號模擬登陸,在本地無需驗證碼,在伺服器跑回回出驗證碼,在伺服器端人工登錄多次後,仍無解。
十分好奇它的常用登錄地機制。難道是伺服器的IP地址早已被列入黑名單?
最後經過多次實驗,它並不判斷常用登錄地,它只在註冊時所在IP不跳驗證碼→_→
果斷在伺服器端註冊了一個賬號,然後就可以愉快的爬了 (ノ^_^)ノ
說一個我所知的關於爬蟲的有趣的事,這是真實故事,但隱去了具體公司名。
有一個to B業務的公司,在自己的網站上有服務產品報價,服務產品周期很短,而且價格也會有浮動,作為B的客戶在購買的時候可以看見報價,這些B可沒有一個SB,他們在購買之前回去看一看另一個網站,那個網站是競爭對手,提供類似的服務,一樣有服務產品報價,然後客戶當然選價格低的。
這個博弈遊戲就成了這樣:兩個網站需要盯著對方的價格,然後在不賠本的情況下讓自己的出價更低。
於是,公司的技術人員開始討論,如何能夠自動化調整自家網站的價格,比如一個服務對方網站報價25.00,那就通過爬蟲抓取到,把自家報價報價自動調整成24.99,只少一分錢,也足夠讓客戶選擇我們家的而拋棄對方家的……嗯,這就是科技的力量。
方案很快實施,果然佔了優勢,很多客戶倒向了這一邊。
不過,很快對方網站也發現了這個問題,他們同樣也寫了爬蟲,來抓取這邊的網站,然後自動調整價格,同時,因為他們知道爬蟲的存在,所以也開始反爬,把價格換成一個包含數字的圖片。
還好,第一個網站快速作出了調整,也把價格換成了圖片,畢竟這不是很難的事情。
於是,雙方的競爭力又回到均衡狀態。
但是,為了重新獲得優勢,雙方都開始了更進一步的較量,幾乎同時推出了讀取圖片中數字的功能,而且,因為料到對方會做出對應調整,在自己網站的價格圖片上增加了水印,呵呵,讓你爬,爬了也讀不出來,嗯,連自家的爬蟲也讀不出來。
又經過若干次技術交鋒,最後的結果基本上就是雙方的價格都用扭曲的圖片顯示,雙方都無法讀取對方的圖片內容,只留下客戶有點納悶:怎麼價格都是歪歪扭扭的數字而且還畫著一些莫名其妙的線條呢?
中國互聯網就是這樣爬與反爬的遊戲。
青銅反爬:請求頭上做點基本的檢驗
白銀反爬:限制訪問頻率,封 IP,跳圖形驗證碼,infinite redirect loop,需要登錄
黃金反爬:前端 js script 實時計算 parameter 加給請求在後端進行驗證
鉑金反爬:翻頁使用 ajax ,沒有 pagination ,數據以 json 形式在前端非同步載入,驗證參數不正確隨機截斷 html
鑽石反爬:異地登錄需要手機簡訊驗證,拖動、拼圖等各類人機驗證碼
王者反爬:我們公司的前端寫的代碼讓你的爬蟲在 parse html 階段的難度上升為 nlp :)
我曾經想爬「吳音小字典」上的字音數據。
比如,在這個網站上查詢「蛤」字,得到的結果是這樣的:
但是,到源代碼里去找「蛤」和「keh」,卻發現是圖片:
圖片是由程序現場生成的,具體內容是從「text」參數解碼出來的。改變該參數的值,生成的圖片內容仍然是文字,但就是完全不同的文字了。
由於我搞不懂這裡的編碼和解碼方式,要想爬就只能下載圖片然後做 OCR 了。由於嫌麻煩,我就放棄了。
數值都是svg
我們自己弄了個假數據集合,幾十萬條,通過探針獲取請求數據,如果判斷為爬蟲,就對用戶http重定向到假數據裡面,返回假數據,不過假數據跟真數據一模一樣,差別非常小 造成對方拿到數據 都無法判斷數據正常與否
技術用到了 iprobe lua-jit pipelineDB aerospike geo庫 等抓取代理時遇到過
那麼,貢獻一個十分鐘解決爬蟲問題的反爬蟲方案吧。以下,GO~
---
以下回答將描述一種盡量簡單的反爬蟲方案,可以在十幾分鐘內解決部分簡單的爬蟲問題,緩解惡意攻擊或者是系統超負荷運行的狀況;至於複雜的爬蟲以及更精準的防禦,需要另外討論。作者依然是忙得沒有白天黑夜的、我們豈安科技的CTO,陸文童鞋。
【一個超輕量級反爬蟲方案】整套方案會盡量簡單易懂,不會涉及到專門的程序開發,同時盡量利用現有的組件,避免額外組件的引入。內容上主要分為三大部分:
- 訪問數據獲取。採集用戶的訪問數據,用來做爬蟲分析的數據源
- 爬蟲封禁。當找到爬蟲後,想辦法去阻斷它後續的訪問
- 爬蟲分析。示例通過簡單策略來分析出爬蟲
簡單的數據獲取
數據獲取是做好反爬蟲系統的關鍵,常見的幾種模式
本篇,採用nginx的日誌方式,這種只需要通過對常見的nginx最簡單的配置就能從遠程獲取相應的訪問日誌。
官方nginx配置:
log_format warden "" "$remote_addr" "$remote_port" "$server_addr" "$server_port" "$request_length" "$content_length" "$body_bytes_sent" "$request_uri" "$host" "$http_user_agent" "$status" "$http_cookie" "$request_method" "$http_referer" "$http_x_forwarded_for" "$request_time" "$sent_http_set_cookie" "$content_type" "$upstream_http_content_type" "$request_body"
";
access_log syslog:server=127.0.0.1:9514 warden ;
tengine配置(編譯時帶上--with-syslog)
log_format warden "" "$remote_addr" "$remote_port" "$server_addr" "$server_port" "$request_length" "$content_length" "$body_bytes_sent" "$request_uri" "$host" "$http_user_agent" "$status" "$http_cookie" "$request_method" "$http_referer" "$http_x_forwarded_for" "$request_time" "$sent_http_set_cookie" "$content_type" "$upstream_http_content_type" "$request_body"
";
access_log syslog:user::127.0.0.1:9514 warden ;
這裡面需要注意的是:
- 由於較老的nginx官方版本不支持syslog,所以tengine在這塊功能上做了單獨的開發(需要通過編譯選項來啟用),在不確定的情況下,請修改配置 文件後先使用(nginx -t)來測試一下,如果不通過,需要重新在configure時加上syslog選項,並編譯。
- 盡量獲取了跟爬蟲相關的數據欄位,如果有定製的http header,可以自行加上
- 採用udp方式來發送syslog,可以將訪問日誌發送給遠端分析服務,同時udp的方式保證nginx本身不會受到影響
- 訪問日誌拿不到響應的具體內容(nginx有辦法搞定,但有代價),無法支持業務相關的防護
簡單的爬蟲封禁
反爬蟲最後的生效,需要靠合理的封禁模式,這裡比較幾種模式:
本段將介紹基於iptables的方案,雖然適用範圍較小;但是依賴少,可以通過簡單配置linux就能達到效果。
第一步
安裝ipset。ipset擴充了iptables的基本功能,可以提供更加高效的訪問控制
# centos 6.5上面安裝非常簡單
sudo yum install -y ipset
第二步
在iptables中建立相應的ipset,來進行訪問許可權的封禁
# 新增用於封禁的ipset
sudo ipset -N --exist warden_blacklist iphash
# 增加相應的iptables規則
sudo iptables -A INPUT -m set --set warden_blacklist src -j DROP
# 保存iptables
sudo service iptables save
第三步
獲取當前封禁的ip黑名單,並導入到iptables裡面去
sudo ipset --exist destroy warden_blacklist_tmp; sudo ipset -N warden_blacklist_tmp iphash; echo "1.1.1.1,2.2.2.2" | tr , "
" | xargs -n 1 -I {} sudo ipset -A warden_blacklist_tmp {} ; sudo ipset swap warden_blacklist_tmp warden_blacklist
這裡為了儘可能的提升效率,作了以下事情:
- 建立臨時ipset,方便做操作
- 將當前封禁黑名單中的ip提取出來,加入到此ipset(示例中用了最簡單的echo來展示,實際可相應調整)
- 將ipset通過原子操作與iptables正在使用的ipset作交換,以最小的代價將最新的黑名單生效
簡單的爬蟲策略
要能精確的分析爬蟲,需要強大的數據分析平台和規則引擎,來分析這個IP/設備/用戶分別在短時間區間/長時間範圍里的行為特徵和軌跡,這裡涉及到了非常複雜的數據系統開發,本文將通過簡單的shell腳本描述比較簡單的規則
例子1,封禁最近100000條中訪問量超過5000的ip
nc -ul 9514 | head -100000 | awk -F "" "" "{print $2}" | sort | uniq -c | sort -nr | awk "$1&>=5000 {print $2}"
這裡面:
- udp服務監聽nginx發過來的syslog消息,並取10000條,找到其中每條訪問記錄的ip
- 通過sort 和uniq來獲取每個ip出現的次數,並進行降序排列
- 再通過awk找到其中超過閾值的ip,這就得到了我們所需要的結果。
例子2,封禁最近100000條中user agent明顯是程序的ip
nc -ul 9514 | head -100000 | awk -F "" "" "$10 ~ /java|feedly|universalfeedparser|apachebench|microsoft url control|python-urllib|httpclient/ {print $2}" | uniq
這裡面:
- 通過awk的正則來過濾出問題agent,並將相應ip輸出
- 關於agent的正則表達式列出了部分,可以根據實際情況去調整和積累
當然,這裡只是列舉了簡單的例子,有很多的不足之處:
- 由於只採用了shell,規則比較簡單,可以通過擴展awk或者其他語言的方式來實現更複雜的規則
- 統計的窗口是每100000條,這種統計窗口比較粗糙,好的統計方式需要在每條實時數據收到是對過去的一小段時間(例如5分鐘)重新做統計計算
- 不夠實時,無法實時的應對攻擊行為;生產環境中,需要毫秒級的響應來應對高級爬蟲
- ......
拼起來
所有模塊組合起來,做一個完整的例子。假設:
- 負載均衡192.168.1.1,使用了官方nginx,並配置了syslog發往192.168.1.2
- 192.168.1.2啟動nc server,每隔一段時間進行分析,找出問題ip,並吐給192.168.1.1
- 192.168.1.1通過iptables進行阻攔,數據來源於192.168.1.2的分析機器
除了nginx配置和iptables基本配置,前幾段的配置略作改動:
### nginx conf@192.168.1.1
log_format warden "" "$remote_addr" "$remote_port" "$server_addr" "$server_port" "$request_length" "$content_length" "$body_bytes_sent" "$request_uri" "$host" "$http_user_agent" "$status" "$http_cookie" "$request_method" "$http_referer" "$http_x_forwarded_for" "$request_time" "$sent_http_set_cookie" "$content_type" "$upstream_http_content_type" "$request_body"
";
access_log syslog:server=192.168.1.2:9514 warden ;
### 分析@192.168.1.2, 增加了結果會吐,同時每隔60分鐘跑一次,把數據返回給192.168.1.1
while true ; do nc -ul 9514 | head -100000 | awk -F "" "" "{print $2}" | sort | uniq -c | sort -nr | awk "$1&>=5000 {print $2}" | tr "
" "," | awk "{print $0}" | socat - UDP:192.168.1.1:9515 ; sleep 3600 ; done
### 阻斷@192.168.1.1
#基礎配置
sudo ipset -N --exist warden_blacklist iphash
sudo iptables -A INPUT -m set --set warden_blacklist src -j DROP
sudo service iptables save
#動態接收並更新iptables
while true ; do sudo ipset --exist destroy warden_blacklist_tmp; sudo ipset -N warden_blacklist_tmp iphash; socat UDP-LISTEN:9515 - | tr , "
" | xargs -n 1 -I {} sudo ipset -A warden_blacklist_tmp {} ;sudo ipset swap warden_blacklist_tmp warden_blacklist ; sudo ipset list ; done
以上只是簡單示例,實際中還是建議換成shell腳本。
總結
本文列出一種簡單的反爬蟲方案,由於過於簡單,可以當做概念示例或者是救急方案,如果需要進一步深化,需要在以下方面去加強:
- 強化數據源,可以通過流量獲得全量數據。目前爬蟲等網路攻擊逐漸轉向業務密切相關的部分,往錢的方向靠近,所以需要更多的業務數據去支撐,而不僅僅是訪問日誌
- 更靈活的阻斷,需要有多種阻斷手段和略複雜的阻斷邏輯
- 除卻ip,還需要考察用戶、設備指紋等多種追蹤方式,應對移動環境和ipv6環境下,「IP」這一信息的力不從心
- 強化規則引擎和模型,需要考察更多用戶行為的特徵,僅僅從頻率等手段只等應對傻爬蟲,同時會造成誤殺率更高
- 建立數據存儲、溯源、統計體系,方便分析人員去分析數據並建立新的模型和規則。反爬蟲是一件持續性行為,需要良好的平台來支撐
- 可以根據實際需要去做好反爬蟲系統的集成。比如nginx數據--&>反爬系統--&>nginx阻斷;F5數據--&>反爬系統--&>F5阻斷
在微博上看到過某位同學總結的,反正是讓我很開眼界了。
現在知乎很多童鞋入門Python都是以requests+BeautifulSoup的小爬蟲作為練習的,
然後可能還會做一些數據清洗,再來簡單地統計分析一下,
但一定要評估下爬取的數據質量,要不很容易掉進坑裡去的。
你分析報告的數據實錘可能完全都是錯誤的。
鏈接如下:
反擊爬蟲,前端工程師的腦洞可以有多大?litten.me在頁面里放上反爬蟲工程師的招聘廣告
又想起來一個…直接辦阿里騰訊vps的公網ip端我就遇到一個。
頁面通過js分步載入的,js也很複雜,這不算什麼。
然而並沒有發現內容對應的json請求數據。
當時我是崩潰的,所有請求都看過了,fiddler攔截了所有請求一個個分析,甚至檢查了所有的css和圖片,然並卵。
最後發現內容就在原html頁面的一條很長很長的js語句裡面。由於查看源碼對一行長度究竟有多長沒有太大感覺,就以為內容這麼多應該不會在那裡。
還有一個:起手100個換行有時候可以讓你懷疑人生。
最近剛好在做反爬蟲的需求,簡單的整理一下思路。
首先需要明確的是,web上的爬蟲與反爬蟲永遠是一個博弈的過程。爬蟲不能絕對的禁掉,只能儘可能的避免爬蟲對於正常業務的影響。反爬蟲的效果取決於使用的策略的複雜度,當然策略越複雜可能對於介面或者頁面的性能影響越大。
對於介面的防抓取大概有如下的思路:
1,token鑒權,後端生成加密的token傳給前端,前端生成加密的key帶上token去請求介面。後端一通校驗。key和token可以使用aes加密,後端反解校驗。也可以md5,後端按照策略生成對比。通過這種方式,抓取者要是直接抓介面,顯然難度增加了除非運行js腳本。這樣一部分的低端抓取者就得懵逼一陣子。當然前端腳本的混淆是必須的。
2,假設抓取這突破了第一道防線想辦法破解了token鑒權。那手裡就拿到了真實的數據了。這時候我們就需要再考慮對敏感數據進行加密了,比如價格。樓上有提到qunar的價格問題,實際上這種方式應該叫做dom位移,其他的我不說了。另外美團糯米直接上了一個圖片,圖片上直接給出一個數字序列,之後肯定在某個地方有個mapping來隱射數字對應關係。這種方式有個問題就是抓取者要是稍微細心一點就發現了,這個有趣的事情。還有一種方式和美團的處理方式有異曲同工的地方,那就是使用字體文件來做敏感數據的混淆。好處在於這種方式的mapping是不可見的。至於怎麼破解,biubiubiu...
3,除了這些並不能達到預期的效果,還可能需要配合一些http參數的策略。這裡就大有作為了,user-agent,cookie,ip黑白名單想怎麼玩就怎麼玩。不幸的是,一旦被發現偽造幾乎沒有什麼成本。好消息是,抓取者的成本又升高了。
4,最後想表達的一點是,海量的日誌信息是巨大的財富。要是把人工智慧,機器學習應用到反爬蟲,想想都激動的無法自拔。。。。
這是一個牛人寫的一種,讓普通用戶輕鬆看得到數據,但是爬蟲人員難以抽取的網頁源碼。
採用display:none來隨機化網頁源碼
總所周知,我們在爬蟲中想要選出某個需要的數據
,可以使用xpath或者正則這類字元串的操作,然而必然需要對方的網站有一定規律,才能合理的抽出數據,因此也有使用nodisplay這個屬性,讓顯示的後台代碼十分混亂,但是前台呈現給用戶的數據並不會混亂比如:http://proxy.goubanjia.com/
如圖,我使用chrome來檢測這ip部分的源代碼的時候就會出現後台亂七八糟的顯示情況,
有網站還會隨機類的名字,讓更加不好捕捉。關於評論區朋友們說這簡單好破的請舉個栗子?
以前寫了一篇記錄文,運用phantomjs無頭瀏覽器破解四種反爬蟲技術 | | URl-team
推薦閱讀:
※python爬蟲實習?
※只針對 Python 爬蟲,該如何學習?
※pymongo 查詢時,顯示循環不同,為何效率相差百倍?
※abaqus的二次開發為何用python語言?