python 反反爬蟲策略之js動態加密url破解
這次這個爬蟲廢了我好幾天時間,第一次遇到js反爬蟲策略,瞬間被打趴下了。不過研究了好幾天之後終於是搞定了,求助的一個朋友,最後的原理我可能也不是太清楚,寫下來,記錄一下,有遇到類似問題的可以參考一下。
這個反爬蟲策略,具體是這樣的,當我寫了一個這樣的get請求。
content = requests.get(wanzurl).content
前兩百條,都會返回網頁原始碼,然後我能得到我想要的資料,但是每24小時你通過程式碼訪問的超過200條之後,就會返回一個js指令碼,神奇的指令碼,同一個網址,每次訪問返回的指令碼都不一樣,js指令碼是這樣的。
<script type="text/javascript"> function UGy(UGy_) { function gn() { return getName(); }; return gn(); return 'UGy' } function o9P() { 'return o9P'; return '17' } function getName() { var caller = getName.caller; if (caller.name) { return caller.name } var str = caller.toString().replace(/[\s]*/g, ""); var name = str.match(/^function([^\(]+?)\(/); if (name && name[1]) { return name[1]; } else { return ''; } } W2 = 'v'; function do(do_) { function w() { return getName(); }; return w(); return 'do' } E0zT = function() { 'return E0zT'; return 'id='; }; function Vo() { 'Vo'; function _V() { return '=' }; return _V(); } _V4R9e = 'assign'; _x2vzv = 'replace'; _riss5 = location; function CY(CY_) { function f() { return getName(); }; return f(); return 'CY' } gw4G = '&_d'; function oPe(oPe_) { function ad() { return getName(); }; return ad(); return 'oPe' } function M7n5() { 'return M7n5'; return '.ph' } eF9 = function(eF9_) { var _e = function(eF9_) { 'return eF9'; return eF9_; }; return _e(eF9_); }; function oq8() { 'oq8'; function _o() { return 'p?' }; return _o(); } kZsu = function() { 'return kZsu'; return 'f56'; }; xK9 = function(xK9_) { 'return xK9'; return xK9_; }; eC = function() { 'eC'; var _e = function() { return 'o' }; return _e(); }; function CjJ(CjJ_) { function si() { return getName(); }; return si(); return 'CjJ' } function on(on_) { function m() { return getName(); }; return m(); return 'on' } function b2(b2_) { function _b(b2_) { function u() { return getName(); } function b2_() {} return u(); return b2_ }; return _b(b2_); } function KX0(KX0_) { function _K(KX0_) { function th() { return getName(); } function KX0_() {} return th(); return KX0_ }; return _K(KX0_); } Nm = function() { 'return Nm'; return 'o'; }; function VlK() { 'VlK'; function _V() { return 'd=' }; return _V(); } _MBGz6 = 'href'; _MG5Qx = window; gm = '5'; location = (function(g7Z_) { return (function(g7Z_) { return g7Z_; })(g7Z_); })('/f') + eC() + (function() { 'return qy'; return 'r' })() + b2('f2') + (function() { 'return OB'; return (function() { return 'm'; })(); })() + M7n5() + oq8() + on('f6') + Nm() + VlK() + W2 + (function(CJL_) { return (function(CJL_) { return CJL_; })(CJL_); })('ie') + do('ze') + KX0('Klt') + (function(DnX_) { return (function(DnX_) { return DnX_; })(DnX_); })('re') + oPe('nUH') + eF9('&t') + E0zT() + gm + xK9('67') + '57' + (function() { 'return bK'; return '9' })() + gw4G + CjJ('p49') + UGy('bNQ') + Vo() + o9P() + CY('S3') + '55' + kZsu(); _MG5Qx.href = (function(g7Z_) { return (function(g7Z_) { return g7Z_; })(g7Z_); })('/f') + eC() + (function() { 'return qy'; return 'r' })() + b2('f2') + (function() { 'return OB'; return (function() { return 'm'; })(); })() + M7n5() + oq8() + on('f6'); </script>
看起來刁刁的,於是我嘗試看一波js程式碼,看了一天之後,搞得我噁心的要死,於是求助我朋友,得到部分解密程式碼,
var location{
assign : set
}
var url = "";
function set(s){
url = s;
}
function get(){
return url;
}
一共有四種解密的程式碼,已經全都寫好了。大概講一下思路,先將返回的js程式碼格式化,然後
看到location呼叫了assign函式,然後定義一個結構是location的函式
var location{ assign : set } var url = ""; function set(s){ url = s; } function get(){ return url; }
然後python呼叫get函式,就能返回這個js腳本里面的引數。將寫好的js程式碼,加到返回的js腳本里。
這個伺服器返回的js指令碼直接執行的話,會在當前的url後面新增一個引數
解密之後,把解出來的引數加到原來的連結之後再次發起請求,伺服器就會返回資料。
然後一個通過js動態新增引數的反爬蟲策略被完美破解。其中的js程式碼也是經過混淆,非常的難以看懂,主要就是找到js腳本里面的location,window,和href幾個引數,將即將返回的引數,通過新增js程式碼,直接取出來。
整個破解原理大概是:多次請求之後,伺服器不再直接返回原始碼,而是返回一個js檔案,這個js檔案執行之後,最終會向url欄新增一串引數,我們寫一個函式,將它要返回給瀏覽器url位址列的引數,返回出來就好了。。。
不用管它加密的邏輯,反正他最終都要返回一個引數到url位址列,也就是window.location.href的部分,去看這三個單詞相關的程式碼,然後寫程式碼將最後的引數返回到程式碼裡進行拼接。