成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python爬蟲抓取技術(shù)的門道

開發(fā) 后端
web是一個開放的平臺,這也奠定了web從90年代初誕生直至今日將近30年來蓬勃的發(fā)展。

web是一個開放的平臺,這也奠定了web從90年代初誕生直至今日將近30年來蓬勃的發(fā)展。然而,正所謂成也蕭何敗也蕭何,開放的特性、搜索引擎以及簡單易學(xué)的html、css技術(shù)使得web成為了互聯(lián)網(wǎng)領(lǐng)域里最為流行和成熟的信息傳播媒介;但如今作為商業(yè)化軟件,web這個平臺上的內(nèi)容信息的版權(quán)卻毫無保證,因為相比軟件客戶端而言,你的網(wǎng)頁中的內(nèi)容可以被很低成本、很低的技術(shù)門檻實現(xiàn)出的一些抓取程序獲取到,這也就是這一系列文章將要探討的話題—— 網(wǎng)絡(luò)爬蟲 。

[[268331]]

 

有很多人認(rèn)為web應(yīng)當(dāng)始終遵循開放的精神,呈現(xiàn)在頁面中的信息應(yīng)當(dāng)毫無保留地分享給整個互聯(lián)網(wǎng)。然而我認(rèn)為,在IT行業(yè)發(fā)展至今天,web已經(jīng)不再是當(dāng)年那個和pdf一爭高下的所謂 “超文本”信息載體 了,它已經(jīng)是以一種 輕量級客戶端軟件 的意識形態(tài)的存在了。而商業(yè)軟件發(fā)展到今天,web也不得不面對知識產(chǎn)權(quán)保護(hù)的問題,試想如果原創(chuàng)的高質(zhì)量內(nèi)容得不到保護(hù),抄襲和盜版橫行網(wǎng)絡(luò)世界,這其實對web生態(tài)的良性發(fā)展是不利的,也很難鼓勵更多的優(yōu)質(zhì)原創(chuàng)內(nèi)容的生產(chǎn)。

未授權(quán)的爬蟲抓取程序是危害web原創(chuàng)內(nèi)容生態(tài)的一大元兇,因此要保護(hù)網(wǎng)站的內(nèi)容,首先就要考慮如何反爬蟲。

從爬蟲的攻防角度來講

最簡單的爬蟲,是幾乎所有服務(wù)端、客戶端編程語言都支持的http請求,只要向目標(biāo)頁面的url發(fā)起一個http get請求,即可獲得到瀏覽器加載這個頁面時的完整html文檔,這被我們稱之為“同步頁”。

作為防守的一方,服務(wù)端可以根據(jù)http請求頭中的User-Agent來檢查客戶端是否是一個合法的瀏覽器程序,亦或是一個腳本編寫的抓取程序,從而決定是否將真實的頁面信息內(nèi)容下發(fā)給你。

這當(dāng)然是最小兒科的防御手段,爬蟲作為進(jìn)攻的一方,完全可以偽造User-Agent字段,甚至,只要你愿意,http的get方法里, request header的 Referrer 、 Cookie 等等所有字段爬蟲都可以輕而易舉的偽造。

此時服務(wù)端可以利用瀏覽器http頭指紋,根據(jù)你聲明的自己的瀏覽器廠商和版本(來自 User-Agent ),來鑒別你的http header中的各個字段是否符合該瀏覽器的特征,如不符合則作為爬蟲程序?qū)Υ_@個技術(shù)有一個典型的應(yīng)用,就是 PhantomJS 1.x版本中,由于其底層調(diào)用了Qt框架的網(wǎng)絡(luò)庫,因此http頭里有明顯的Qt框架網(wǎng)絡(luò)請求的特征,可以被服務(wù)端直接識別并攔截。

除此之外,還有一種更加變態(tài)的服務(wù)端爬蟲檢測機(jī)制,就是對所有訪問頁面的http請求,在 http response 中種下一個 cookie token ,然后在這個頁面內(nèi)異步執(zhí)行的一些ajax接口里去校驗來訪請求是否含有cookie token,將token回傳回來則表明這是一個合法的瀏覽器來訪,否則說明剛剛被下發(fā)了那個token的用戶訪問了頁面html卻沒有訪問html內(nèi)執(zhí)行js后調(diào)用的ajax請求,很有可能是一個爬蟲程序。

如果你不攜帶token直接訪問一個接口,這也就意味著你沒請求過html頁面直接向本應(yīng)由頁面內(nèi)ajax訪問的接口發(fā)起了網(wǎng)絡(luò)請求,這也顯然證明了你是一個可疑的爬蟲。知名電商網(wǎng)站Amazon就是采用的這種防御策略。

以上則是基于服務(wù)端校驗爬蟲程序,可以玩出的一些套路手段。

基于客戶端js運(yùn)行時的檢測

現(xiàn)代瀏覽器賦予了JavaScript強(qiáng)大的能力,因此我們可以把頁面的所有核心內(nèi)容都做成js異步請求 ajax 獲取數(shù)據(jù)后渲染在頁面中的,這顯然提高了爬蟲抓取內(nèi)容的門檻。依靠這種方式,我們把對抓取與反抓取的對抗戰(zhàn)場從服務(wù)端轉(zhuǎn)移到了客戶端瀏覽器中的js運(yùn)行時,接下來說一說結(jié)合客戶端js運(yùn)行時的爬蟲抓取技術(shù)。

剛剛談到的各種服務(wù)端校驗,對于普通的python、java語言編寫的http抓取程序而言,具有一定的技術(shù)門檻,畢竟一個web應(yīng)用對于未授權(quán)抓取者而言是黑盒的,很多東西需要一點一點去嘗試,而花費大量人力物力開發(fā)好的一套抓取程序,web站作為防守一方只要輕易調(diào)整一些策略,攻擊者就需要再次花費同等的時間去修改爬蟲抓取邏輯。

此時就需要使用headless browser了,這是什么技術(shù)呢?其實說白了就是,讓程序可以操作瀏覽器去訪問網(wǎng)頁,這樣編寫爬蟲的人可以通過調(diào)用瀏覽器暴露出來給程序調(diào)用的api去實現(xiàn)復(fù)雜的抓取業(yè)務(wù)邏輯。

其實近年來這已經(jīng)不算是什么新鮮的技術(shù)了,從前有基于webkit內(nèi)核的PhantomJS,基于Firefox瀏覽器內(nèi)核的SlimerJS,甚至基于IE內(nèi)核的trifleJS,有興趣可以看看這里和這里 是兩個headless browser的收集列表。

這些headless browser程序?qū)崿F(xiàn)的原理其實是把開源的一些瀏覽器內(nèi)核C++代碼加以改造和封裝,實現(xiàn)一個簡易的無GUI界面渲染的browser程序。但這些項目普遍存在的問題是,由于他們的代碼基于fork官方webkit等內(nèi)核的某一個版本的主干代碼,因此無法跟進(jìn)一些新的css屬性和js語法,并且存在一些兼容性的問題,不如真正的release版GUI瀏覽器運(yùn)行得穩(wěn)定。

這其中最為成熟、使用率高的應(yīng)該當(dāng)屬 PhantonJS 了,對這種爬蟲的識別我之前曾寫過一篇博客,這里不再贅述。PhantomJS存在諸多問題,因為是單進(jìn)程模型,沒有必要的沙箱保護(hù),瀏覽器內(nèi)核的安全性較差。另外,該項目作者已經(jīng)聲明停止維護(hù)此項目了。

如今Google Chrome團(tuán)隊在Chrome 59 release版本中開放了headless mode api,并開源了一個基于Node.js調(diào)用的headless chromium dirver庫,我也為這個庫貢獻(xiàn)了一個centos環(huán)境的部署依賴安裝列表。

Headless Chrome可謂是Headless Browser中獨樹一幟的大殺器,由于其自身就是一個chrome瀏覽器,因此支持各種新的css渲染特性和js運(yùn)行時語法。

基于這樣的手段,爬蟲作為進(jìn)攻的一方可以繞過幾乎所有服務(wù)端校驗邏輯,但是這些爬蟲在客戶端的js運(yùn)行時中依然存在著一些破綻,諸如:

基于plugin對象的檢查

  1. if(navigator.plugins.length === 0) { 
  2.  console.log('It may be Chrome headless'); 

基于language的檢查

  1. if(navigator.languages === '') { 
  2.  console.log('Chrome headless detected'); 

基于webgl的檢查

  1. var canvas = document.createElement('canvas'); 
  2. var gl = canvas.getContext('webgl'); 
  3. var debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); 
  4. var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL); 
  5. var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); 
  6. if(vendor == 'Brian Paul' && renderer == 'Mesa OffScreen') { 
  7.  console.log('Chrome headless detected'); 

基于瀏覽器hairline特性的檢查

  1. if(!Modernizr['hairline']) { 
  2.  console.log('It may be Chrome headless'); 

基于錯誤img src屬性生成的img對象的檢查

  1. var body = document.getElementsByTagName('body')[0]; 
  2. var image = document.createElement('img'); 
  3. image.src = 'http://iloveponeydotcom32188.jg'
  4. image.setAttribute('id''fakeimage'); 
  5. body.appendChild(image); 
  6. image.onerror = function(){ 
  7.  if(image.width == 0 && image.height == 0) { 
  8.  console.log('Chrome headless detected'); 
  9.  } 

基于以上的一些瀏覽器特性的判斷,基本可以通殺市面上大多數(shù) Headless Browser 程序。在這一層面上,實際上是將網(wǎng)頁抓取的門檻提高,要求編寫爬蟲程序的開發(fā)者不得不修改瀏覽器內(nèi)核的C++代碼,重新編譯一個瀏覽器,并且,以上幾點特征是對瀏覽器內(nèi)核的改動其實并不小,如果你曾嘗試過編譯Blink內(nèi)核或Gecko內(nèi)核你會明白這對于一個“腳本小子”來說有多難~

更進(jìn)一步,我們還可以基于瀏覽器的 UserAgent 字段描述的瀏覽器品牌、版本型號信息,對js運(yùn)行時、DOM和BOM的各個原生對象的屬性及方法進(jìn)行檢驗,觀察其特征是否符合該版本的瀏覽器所應(yīng)具備的特征。

這種方式被稱為 瀏覽器指紋檢查 技術(shù),依托于大型web站對各型號瀏覽器api信息的收集。而作為編寫爬蟲程序的進(jìn)攻一方,則可以在 Headless Browser 運(yùn)行時里預(yù)注入一些js邏輯,偽造瀏覽器的特征。

另外,在研究瀏覽器端利用js api進(jìn)行 Robots Browser Detect 時,我們發(fā)現(xiàn)了一個有趣的小技巧,你可以把一個預(yù)注入的js函數(shù),偽裝成一個Native Function,來看看下面代碼:

  1. var fakeAlert = (function(){}).bind(null); 
  2. console.log(window.alert.toString()); // function alert() { [native code] } 
  3. console.log(fakeAlert.toString()); // function () { [native code] } 

爬蟲進(jìn)攻方可能會預(yù)注入一些js方法,把原生的一些api外面包裝一層proxy function作為hook,然后再用這個假的js api去覆蓋原生api。如果防御者在對此做檢查判斷時是基于把函數(shù)toString之后對[native code]的檢查,那么就會被繞過。所以需要更嚴(yán)格的檢查,因為bind(null)偽造的方法,在toString之后是不帶函數(shù)名的,因此你需要在toString之后檢查函數(shù)名是否為空。

這個技巧有什么用呢?這里延伸一下,反抓取的防御者有一種Robot Detect的辦法是在js運(yùn)行時主動拋出一個alert,文案可以寫一些與業(yè)務(wù)邏輯相關(guān)的,正常的用戶點確定按鈕時必定會有一個1s甚至更長的延時,由于瀏覽器里alert會阻塞js代碼運(yùn)行(實際上在v8里他會把這個isolate上下文以類似進(jìn)程掛起的方式暫停執(zhí)行),所以爬蟲程序作為攻擊者可以選擇以上面的技巧在頁面所有js運(yùn)行以前預(yù)注入一段js代碼,把a(bǔ)lert、prompt、confirm等彈窗方法全部hook偽造。如果防御者在彈窗代碼之前先檢驗下自己調(diào)用的alert方法還是不是原生的,這條路就被封死了。

反爬蟲的銀彈

目前的反抓取、機(jī)器人檢查手段,最可靠的還是驗證碼技術(shù)。但驗證碼并不意味著一定要強(qiáng)迫用戶輸入一連串字母數(shù)字,也有很多基于用戶鼠標(biāo)、觸屏(移動端)等行為的行為驗證技術(shù),這其中最為成熟的當(dāng)屬Google reCAPTCHA,基于機(jī)器學(xué)習(xí)的方式對用戶與爬蟲進(jìn)行區(qū)分。

基于以上諸多對用戶與爬蟲的識別區(qū)分技術(shù),網(wǎng)站的防御方最終要做的是封禁ip地址或是對這個ip的來訪用戶施以高強(qiáng)度的驗證碼策略。這樣一來,進(jìn)攻方不得不購買ip代理池來抓取網(wǎng)站信息內(nèi)容,否則單個ip地址很容易被封導(dǎo)致無法抓取。抓取與反抓取的門檻被提高到了ip代理池經(jīng)濟(jì)費用的層面。

機(jī)器人協(xié)議

除此之外,在爬蟲抓取技術(shù)領(lǐng)域還有一個“白道”的手段,叫做robots協(xié)議。Allow和Disallow聲明了對各個UA爬蟲的抓取授權(quán)。

不過,這只是一個君子協(xié)議,雖具有法律效益,但只能夠限制那些商業(yè)搜索引擎的蜘蛛程序,你無法對那些“野爬愛好者”加以限制。

寫在最后

對網(wǎng)頁內(nèi)容的抓取與反制,注定是一個魔高一尺道高一丈的貓鼠游戲,你永遠(yuǎn)不可能以某一種技術(shù)徹底封死爬蟲程序的路,你能做的只是提高攻擊者的抓取成本,并對于未授權(quán)的抓取行為做到較為精確的獲悉。

 

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2017-12-05 09:30:27

2017-04-06 11:12:38

JavaScriptGoogle爬蟲

2018-04-20 17:25:46

Python爬蟲智聯(lián)招聘

2024-04-30 09:33:00

JavaScriptPythonexecjs

2023-12-08 18:05:12

文本爬蟲Python

2022-11-24 10:24:32

2017-12-20 09:35:25

Python爬蟲百度云資源

2018-05-10 12:55:51

大數(shù)據(jù)對比分析面試

2023-11-27 08:51:46

PythonRequests庫

2022-09-14 23:06:45

2023-06-01 13:15:23

2017-05-16 15:33:42

Python網(wǎng)絡(luò)爬蟲核心技術(shù)框架

2022-09-20 07:02:20

網(wǎng)絡(luò)爬蟲反爬蟲

2010-03-09 15:48:06

Python抓取

2017-08-09 15:27:33

python爬蟲開發(fā)工具

2021-03-11 13:56:13

協(xié)議Python網(wǎng)絡(luò)

2020-12-08 06:19:33

爬蟲Dom樹組件

2021-03-18 14:35:36

爬蟲技術(shù)開發(fā)

2010-04-02 14:54:35

高性價比無線路由器

2010-08-16 14:34:31

無線路由器的門道
點贊
收藏

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

主站蜘蛛池模板: 午夜一级黄色片 | 国产 日韩 欧美 制服 另类 | 伊人天堂网 | 91xxx在线观看 | 精品国产乱码久久久久久88av | 日本在线综合 | 久久久久久九九九九 | 中文字幕日韩在线 | 麻豆av一区二区三区久久 | 中文在线一区 | 中文字幕视频在线 | 中文字幕日韩在线 | 国产一区免费 | 中文字幕在线电影观看 | 国产一区二区三区在线观看免费 | 欧美成人h版在线观看 | 精品无码久久久久国产 | 国产精品成人69xxx免费视频 | 日韩欧美一二三区 | 91天堂 | 国产在线高清 | 中文字幕在线中文 | 日韩一区二区三区在线观看 | 亚洲一区视频在线 | 国产精品久久久久久久久久三级 | 密室大逃脱第六季大神版在线观看 | 欧美三级视频 | 99久久久国产精品 | 日韩欧美精品一区 | 久久精品 | 日韩精品在线免费观看视频 | 在线播放一区 | 91精品久久久久久久久久入口 | 黄色高清视频 | 日韩在线免费播放 | 亚洲精品免费在线 | 日本一区视频在线观看 | 国产乱码精品一区二区三区忘忧草 | 亚洲一二三区精品 | 久久综合久久综合久久综合 | 亚洲成人自拍网 |