當前位置:
首頁 > 新聞 > 反擊「貓眼電影」網站的反爬蟲策略

反擊「貓眼電影」網站的反爬蟲策略

* 本文作者:數月亮的孩子,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載



0x01 前言

前兩天在百家號上看到一篇名為《反擊爬蟲,前端工程師的腦洞可以有多大?》的文章,文章從多方面結合實際情況列舉了包括貓眼電影、美團、去哪兒等

大型電商網站的反爬蟲機制。的確,如文章所說,對於一張網頁,我們往往希望它是結構良好,內容清晰的,這樣搜索引擎才能準確地認知它;而反過來,又有一些情景,我們不希望內容能被輕易獲取,比方說電商網站的交易額,高等學校網站的題目等。因為這些內容,往往是一個產品的生命線,必須做到有效地保護。這就是爬蟲與反爬蟲這一話題的由來。本文就以做的較好的「貓眼電影」網站為例,搞定他的反爬蟲機制,輕鬆爬去我們想要的數據!


0x02 常見反爬蟲


從功能上來講,爬蟲一般分為數據採集,處理,儲存三個部分。而作為程序員的我們只關心數據採集部分,處理什麼的還是交給那些數據分析師去搞吧。


一般來說,大多數網站會從三個方面反爬蟲:用戶請求的Headers,用戶行為,網站目錄和數據載入方式。前兩種比較容易遇到,大多數網站都從這些角度來反爬蟲,而第三種則相對比較特殊,一些應用ajax的網站會採用,這樣無疑會增大了爬蟲爬取的難度。


然而,這三種反爬蟲策略則早已有應對的方法和策略。如果遇到了從用戶請求的Headers反爬蟲機制,可以直接在爬蟲中添加Headers,將瀏覽器的User-Agent複製到爬蟲的Headers中;或者將Referer值修改為目標網站域名。對於檢測Headers的反爬蟲,在爬蟲中修改或者添加Headers就能很好的繞過。對於基於用戶行為的反爬蟲其實就是通過限制同一IP短時間內多次訪問同一頁面,應對策略也是很粗暴——使用IP代理,可以專門寫一個爬蟲,爬取網上公開的代理ip,檢測後全部保存起來。有了大量代理ip後可以每請求幾次更換一個ip,即可繞過這種反爬蟲機制。對於最後一種動態頁面反爬蟲機制來講,

selenium+phantomJS框架能夠讓你在無界面的瀏覽器中模擬載入網頁的動態請求,畢竟

selenium可是自動化滲透的神器。


0x03 貓眼反爬蟲介紹


介紹完常見的反爬蟲機制,我們回過頭看看我們今天的主角:貓眼電影的反爬蟲是什麼樣的。



對於每日的電影院票價這一重要數據,源代碼中展示的並不是純粹的數字。而是在頁面使用了font-face定義了字符集,並通過unicode去映射展示。簡單介紹下這種新型的web-fongt反爬蟲機制:使用web-font可以從網路載入字體,因此我們可以自己創建一套字體,設置自定義的字元映射關係表。例如設置0xefab是映射字元1,0xeba2是映射字元2,以此類推。當需要顯示字元1時,網頁的源碼只會是

0xefab

,被採集的也只會是

0xefab

,並不是1:



因此採集者採集不到正確的票價數據:


採集者只能獲取到類似?的數據,並不能知道」?」映射的字元是什麼,實現了數據防採集。而對於正常訪問的用戶則沒有影響,因為瀏覽器會載入css中的font字體為我們渲染好,實時顯示在網頁中。也就是說,除去圖像識別,必須同時爬取字符集,才能識別出數字。


查看貓眼的網站源文件正是如此:



所有的票價信息都是由動態font字體「加密」後得到的。既然知道了原理,我們就繼續發掘,通過分析網站HTML結構,我們發現網站每次渲染票價的font字體都可以在網頁的script標籤中被找到:



字體是由base64加密後存儲在網頁中的,於是乎,上python:

#將base64加密的font文件解密轉存本地
font = re.findall(r"src: url(data:application/font-woff;charset=utf-8;base64,(.*?)) format",response_all)[0]
fontdata=base64.b64decode(font)  
file=open("/home/jason/workspace/1.ttf","wb")  
file.write(fontdata)  
file.close()

我們在爬取時將font文件解密後存儲在本地存儲為ttf文件,留做備用。


前文提到過這種web-font定義了字符集,要通過unicode去映射展示,所以,我們要構建ttf字體文件中unicode映射出來的字元字典:


python代碼:

import fontforge
def tff2Unicode():#將字體映射為unicode列表
   filename = "/home/jason/workspace/1.ttf"
   fnt = fontforge.open(filename)
   for i in fnt.glyphs():
       print i.unicode

我們猜測映射關係如下:



還記得嘛,第三張圖我們爬取到的數據是「綉春刀·修羅戰場 341189 2017-07-20 6號廳 2D 國語 11:10 ?」,我們將「&#」替換成「0」後對應上表得出的票價不是剛好是「29」嘛!


python代碼:

tmp_dic={}
ttf_list = []
def creatTmpDic():#創建映射字典
   tmp_dic={}
   ttf_list = []
   num_list = [-1,-1,0,1,2,3,4,5,6,7,8,9]
   filename = "/home/jason/workspace/1.ttf"
   fnt = fontforge.open(filename)
   ttf_list = []
   for i in fnt.glyphs():
       ttf_list.append(i.unicode)
   tmp_dic = dict(zip(ttf_list,num_list))#構建字典
   return tmp_dic,ttf_list
def tff2price(para = ";",tmp_dic={},ttf_list = []):#將爬取的字元映射為字典中的數字
   tmp_return = ""
   for j in para.split(";"):
       if j != "":
           ss = j.replace("&#","0")
           for g in ttf_list:
               if (hex(g) == ss):
                   tmp_return+=str(tmp_dic[g])
   return tmp_return

好的,到此,我們已經可以說已經完成了對票價「加密」數據的破解啦~還是有點小小的成就感呢!但是,這裡面還是有個很坑的地方:開發者已經想到採集者可以通過分析,知道每一個映射代表的意思,從而進行採集後轉換處理,所以我們每次訪問都是隨機得到一種字體,而且開發者還定期更新一批字體文件和映射表用來加大採集的難度,所以我們在採集的過程中不得不每採集一個頁面就更新一次本地的該網頁的web-font字體,無疑會大大增加爬蟲的爬取成本和爬取效率,所以從一定意義上確實實現了反爬蟲。



參考文獻[點擊原文]


* 本文作者:數月亮的孩子,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

【信息安全有獎問卷】最後的機會!截至7月底,聽到您的聲音!
基於Tor的通訊軟體Briar:斷網也能用的通信軟體
【BlackHat 2017】議題分享:一款潛伏了多年的Mac惡意程序,為何迄今仍「逍遙法外」?

TAG:FreeBuf |

您可能感興趣

《閃電俠》大電影導演敲定!
電影《黑豹》精彩打鬥片段曝光 與反派上演近身肉搏
電影於現實:簡述面臨海盜威脅時,船員的反擊手段
這部電影,痴女們的反擊利器!渣男們的警示之鈴!
《閃點》電影反派曝光,無賴幫、冰霜殺手強勢加盟
《恐怖直播》:絕對讓你震撼的電影
《虛無的焦點》入圍倫敦電影節:愛是想觸碰又縮回的手
沒有鋼鐵俠電影的特效好,卻比蝙蝠俠電影的深度高,科幻電影的引領
區塊鏈遊戲傍上電影《捉妖記》,是還原「電影」,卻無法「另闢蹊徑」?
我們的電影入圍柏林電影節啦!
有關狗狗的電影
針對專業視頻拍攝 富士將發布兩支X系列無反電影鏡頭
神秘巨星:以電影的方式反映社會問題
那些關於電影的電影
《金剛狼》導演痛罵電影彩蛋,居然直言片尾彩蛋是電影垃圾
電影《異獸來襲》好看嗎?《異獸來襲》影評!
【視頻】經典電影鏡頭: 這把狙擊槍真夠細的,所以特意配備了炸藥彈頭的子彈
推薦全球火爆的吃雞遊戲電影原型
女子在電影院看電影玩手機被打,網友:乾的漂亮,女的活該!
由電腦屏幕走向電影銀幕