網站:css
汽車之家:http://club.autohome.com.cn/ 以論壇爲例html
反爬蟲措施:git
在論壇發佈的貼子正文中隨機抽取某幾個字使用span標籤代替,標籤內容位空,但css樣式顯示爲所代替的文。這樣不會github
影響正經常使用戶的閱讀,只是在用鼠標選擇的時候是選不到被替換的文字的,對爬蟲則會形成採集內容不全的影響。瀏覽器
原理分析:ide
先看一下span標籤的樣式函數
截圖是火狐瀏覽器的firebug的html面板。咱們能夠看到正文中每一個span標籤的樣式都是一個文字,咱們只須要找到每一個工具
span標籤的class屬性於文字的對應關係便可還原正文內容,因而我找了一下css樣式是在哪裏定義的。找到了這樣一個文網站
件,在firebug的css面板中能夠看到全部的css文件,而後我嘗試打開了一下這個url,發現結果仍是帖子頁面而非css文件ui
經過抓包也沒有抓到相似這樣的css文件,一番嘗試無果後,我明白了,這個css文件應該是利用js生成的,因而我開始尋
找生成這樣的文件的js代碼,基本上就是拿各類關鍵詞到各個js文件或者源代碼中搜索,例如 ::before、content、hs_kw
等。而後發現js代碼存在於網頁源代碼中,能夠利用搜索 HS_ZY來定位到這段js代碼,下面就是對js代碼的分析破解了,
複製這段js代碼到 http://jsbeautifier.org/ 一個js格式化工具網站。格式化以後,發現js代碼是被混淆過的,這就比較蛋疼
了,幸虧以前也接觸過此類混淆,大概明白混淆的原理,無非就是將變量名隨機替換,將完整代碼拆分後用變量相加之類的,
因而在一番很麻煩的將各類變量手工替換回去以後,大概明白了js代碼的主邏輯。
(function(hZ_) { functionEW_() { = DV_()[decodeURIComponent]('%E3%80%81%E3%80%82%E4%B8%80%E4%B8%8A%E4%B8%8B%E4%B8%8D%E4%BA%86%E4%BA%94%E5%92%8C%E5%9C%B0%E5%A4%9A%E5%A4%A7%E5%A5%BD%E5%B0%8F%E5%BE%88%E5%BE%97%E6%98%AF%E7%9A%84%E7%9D%80%E8%BF%9C%E9%95%BF%E9%AB%98%EF%BC%81%EF%BC%8C%EF%BC%9F' yc_()); = la_((yc_() 23; 3; 19; 17; 9; 1; 8; 12; 18; 13; 2; 4; 16; 5; 6; 21; 15; 11; 22; 14; 24; 0; 10; 7; 20), lf_(;)); = la_((10 _7, 6 _0; 2 _33, 14 _18; 8 _45, 8 _36; 0 _71, 16 _54; 13 _76, 3 _72; 0 _107, 16 _90; 15 _110, 1 _108; 4 _139, 12 _126; 9 _152, 7 _144; 10 _169, 6 _162; 4 _193, 12 _180; 11 _204, 5 _198; 3 _230, 13 _216; 1 _250, 15 _234; 13 _256, 3 _252; 6 _281, 10 _270; 9 _296, 7 _288; 13 _310, 3 _306; 6 _335, 10 _324; 7 _352, 9 _342; 6 _371, 10 _360; 5 _390, 11 _378; 5 _408, 11 _396; 7 _424, 9 _414; 6 _443, 10 _432lf_(;)), yc_(;)); Uj_(); return;; } function mS_() { for (Gx_ = 0; Gx_ < nf_.length; Gx_++) { var su_ = Pn_(nf_[Gx_], ','); var KN_ = ''; for (Bk_ = 0; Bk_ < su_.length; Bk_++) { KN_ += ui_(su_[Bk_]) + ''; } Kx_(Gx_, KN_); } } function NH_(Gx_) { return '.hs_kw' + Gx_ + '_maindC'; } function Ln_() { return '::before { content:' } })(document);
很簡單的邏輯,預先定義好哪幾個字要被替換,上面代碼中的那個不少%的字符串就是被替換的文字串,而後定義好每一個文
字的序號,最後按照文字的序號對文字串進行從新排序並生成css樣式,注意,最一開始的span標籤的class屬性中是有個序
號的,這個序號就是用來定位應該對應哪一個文字。
接下來要作的就是無非就是從js代碼中找到這個文字串,找到文字串的順序,而後進行重排,而後根據span標籤序號對原文
進行反向替換,從而獲得完整的內容。
破解步驟:
簡單整理一下:
一、從js代碼中找到被替換的文字串和順序
二、重排文字串
三、對原文中span標籤根據class序號進行替換
其實二、3都比較簡單,重點是第一步,找到被替換的文字串和順序,因爲源代碼中js代碼是被混淆過的,沒法直接看出哪一個
是文字串,因此首先應該對js代碼進行反混淆,這個反混淆也不是說非得完整的還原全部的js代碼,其實只要能反混淆到能
讓咱們看出文字串和順序是什麼就好了。
說一下反混淆的思路,其實很簡單。就是執行起來比較麻煩而已,混淆是利用將一個簡單的變量定義成複雜的js代碼的方法
實現的,但這種混淆方式實際上是有限的(這個有限指的是混淆用的工具在生成混淆代碼時確定是人爲預先定義好了幾種模式
,人爲定義的確定是有限的,只要你把全部的模式找出來,就能夠還原了)。舉個例子
function iq_() { 'return iq_'; return '3'; }
這段代碼其實你能夠簡單的認爲就是變量iq()等於'3',使用正則匹配這樣的代碼模式,而後提取關鍵字:函數名和最後一個
return的值,而後將提取到的信息保存起來用於對js代碼進行全文替換。
function cz_() { function _c() { return 'cz_'; }; if (_c() == 'cz__') { return _c(); } else { return '84'; } }
這段代碼複雜了一些,增長了判斷,不過也簡單,利用正則匹配這樣的模式,而後提取關鍵字:函數名、第一個return的值,
判斷中==後面的值,最後一個return的值,而後本身進行判斷來肯定cz_()的值應該是多少,保存起來進行全文替換。
以此類推,每種模式均可以使用正則來提取關鍵字並進行全文替換來反混淆,最後咱們會獲得一個大概被還原的js代碼,其
中的文字串和順序都清晰可見,再使用正則匹配出來就能夠了。須要注意的一點是有時候被替換的不是單個文字,而是一些
詞語,這是找到的順序是"3,1;23,5"這樣的,不過這些小伎倆應該不算什麼,很好解決。
PS1:
發現一種新的模式,之前沒注意,span的class屬性hs_kw後面還有一串字符,估計是用來標示類別的,通常的網頁
上只有一種class,出現多種的時候對應的源碼中就會存在多段js代碼,每段js代碼對應一種class,關鍵是找到js代碼對應的
class類型,而後分類型替換就好了。
結語:
這個建議你們本身動手作一下,仍是比較有意思的,完整的破解代碼見個人github
https://github.com/duanyifei/antispider/blob/master/autohome.py