<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          web爬蟲抓取技術的門道,對于網絡爬蟲技術的攻與防

          時間:?2017-12-08閱讀:?1133標簽:?爬蟲
          本文首發于我的個人博客,同步發布于cnode社區,非商業轉載請注明出處,商業轉載請閱讀原文鏈接里的法律聲明。 


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

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

          未授權的爬蟲抓取程序是危害web原創內容生態的一大元兇,因此要保護網站的內容,首先就要考慮如何反爬蟲。

          從爬蟲的攻防角度來講

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

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

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

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

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

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

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

          基于客戶端js運行時的檢測

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

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

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

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

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

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

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

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

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

          基于plugin對象的檢查

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

          基于language的檢查

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

          基于webgl的檢查

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

          基于瀏覽器hairline特性的檢查

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

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

          var body = document.getElementsByTagName('body')[0];
          var image = document.createElement('img');
          image.src = 'http://iloveponeydotcom32188.jg';
          image.setAttribute('id', 'fakeimage');
          body.appendChild(image);
          image.onerror = function(){
              if(image.width == 0 && image.height == 0) {
                  console.log('Chrome headless detected');
              }
          }

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

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

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

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

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

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

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

          反爬蟲的銀彈

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

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

          機器人協議

          除此之外,在爬蟲抓取技術領域還有一個“白道”的手段,叫做robots協議。你可以在一個網站的根目錄下訪問/robots.txt,比如讓我們一起來看看github的機器人協議,Allow和Disallow聲明了對各個UA爬蟲的抓取授權。

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

          寫在最后

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

          這篇文章中提到的對于驗證碼的攻防其實也是一個較為復雜的技術難點,在此留一個懸念,感興趣可以加關注期待后續文章進行詳細闡述。

          另外,歡迎對抓取方面感興趣的朋友關注我的一個開源項目webster, 項目以Node.js 結合Chrome headless模式實現了一個高可用性網絡爬蟲抓取框架,借以chrome對頁面的渲染能力, 可以抓取一個頁面中 所有的js及ajax渲染的異步內容;并結合redis實現了一個任務隊列,使得爬蟲程序可以方便的進行橫向、縱向的分布式擴展。部署起來很方便,我已經為webster提供了一個官方版的基礎運行時docker鏡像,如果你想先睹為快也可以試試這個webster demo docker鏡像



          吐血推薦

          1.站長廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入...

          2.休閑娛樂: 直播/交友    優惠券領取   網頁游戲   H5游戲

          鏈接: http://www.modern-decoration.com.cn/article/detial/236

          javascript可以爬蟲嗎?

          網絡爬蟲(又被稱為網頁蜘蛛,網絡機器人),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。

          nodejs能爬蟲么?

          nodejs可以爬蟲。Node.js出現后,爬蟲便不再是后臺語言如PHP,Python的專利了,盡管在處理大量數據時的表現仍然不如后臺語言,但是Node.js異步編程的特性可以讓我們在最少的cpu開銷下輕松完成高并發的爬取。

          爬蟲是什么嗎?你知道爬蟲的爬取流程嗎?

          你了解爬蟲是什么嗎?你知道爬蟲的爬取流程嗎?你知道怎么處理爬取中出現的問題嗎?如果你回答不出來,或許你真的要好好看看這篇文章了!網絡爬蟲(Web crawler),是一種按照一定的規則

          網絡爬蟲程序員被抓,我們還敢爬蟲嗎?

          某大數據科技公司老板丟給一個小小的程序員一個網站,告訴他把這個網站的數據抓取下來,咱們做一做分析。這個小小的程序員就吭哧吭哧的寫了一段抓取代碼,測試了一下,程序沒問題,可以正常的把這個網站的數據給抓取下來

          不會這幾個庫,都不敢說我會Python爬蟲

          很多朋友不知道Python爬蟲怎么入門,怎么學習,到底要學習哪些內容。今天我來給大家說說學習爬蟲,我們必須掌握的一些第三方庫。廢話不多說,直接上干貨。

          8個Python爬蟲框架

          Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。 可以應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。pyspider 是一個用python實現的功能強大的網絡爬蟲系統,能在瀏覽器界面上進行腳本的編寫

          node可以做爬蟲嗎?

          node可以做爬蟲,下面我們來看一下如何使用node來做一個簡單的爬蟲。node做爬蟲的優勢:第一個就是他的驅動語言是JavaScript。JavaScript在nodejs誕生之前是運行在瀏覽器上的腳本語言,其優勢就是對網頁上的dom元素進行操作

          node爬蟲實踐總結

          網絡爬蟲 (又被稱為網頁蜘蛛,網絡機器人,在 FOAF 社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。隨著web2.0時代的到來,數據的價值愈發體現出來。

          node.js中Puppeteer爬蟲

          Puppeteer是谷歌官方出品的一個通過DevTools協議控制headless Chrome的Node庫。可以通過Puppeteer的提供的api直接控制Chrome模擬大部分用戶操作來進行UI Test或者作為爬蟲訪問頁面來收集數據

          使用Node.js爬取任意網頁資源并輸出高質量PDF文件到本地

          本文適合無論是否有爬蟲以及 Node.js 基礎的朋友觀看~如果你是一名技術人員,那么可以看我接下來的文章,否則,請直接移步到我的 github 倉庫,直接看文檔使用即可

          fly63.com版權所有,內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网