1. 程式人生 > >python 反反爬蟲策略之js動態加密url破解

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的部分,去看這三個單詞相關的程式碼,然後寫程式碼將最後的引數返回到程式碼裡進行拼接。