王朝陽,范伊紅,李夢丹,忽愛平
(河南科技大學(xué)軟件學(xué)院,河南 洛陽 471000)
在互聯(lián)網(wǎng)的大千世界里,Python網(wǎng)絡(luò)爬蟲已經(jīng)成為程序員對某個網(wǎng)站數(shù)據(jù)獲取、數(shù)據(jù)分析的一項(xiàng)重要的工具。爬蟲使人們的生活更加便利,尤其是其廣泛運(yùn)用于搜索引擎、數(shù)據(jù)收集、廣告過濾等日常生活中的各個方面。如今,網(wǎng)絡(luò)爬蟲技術(shù)的基本實(shí)現(xiàn)方法不計(jì)其數(shù),運(yùn)用簡單的互聯(lián)網(wǎng)技術(shù)就能獲取完整的爬蟲代碼,故本文不再復(fù)述這些代碼,而主要聊聊一種爬蟲中所用到的JavaScript逆向技術(shù)(下文簡稱“JS逆向技術(shù)”),這種技術(shù)主要是為了解決網(wǎng)絡(luò)數(shù)據(jù)抓取時所遇到的參數(shù)加密、數(shù)據(jù)加密等問題[1]。
當(dāng)順利抓取到網(wǎng)頁的HTML代碼時,有一部分網(wǎng)站,例如某翻譯、某土地市場網(wǎng)等,夾雜著許多的加密數(shù)據(jù),或者是一些看不懂的參數(shù),這些數(shù)據(jù)會阻礙下一步的解析和運(yùn)用,這時就需要運(yùn)用JS逆向技術(shù)反解JS代碼對這些數(shù)據(jù)進(jìn)行解密,從而重寫并模擬JS操作。
本文就以某翻譯網(wǎng)站為例,來解析Python環(huán)境下的JS逆向技術(shù)的實(shí)現(xiàn)過程。也許這個網(wǎng)站解析出的數(shù)據(jù)價(jià)值性沒有想象的高,但目的不是獲取有價(jià)值的數(shù)據(jù),而是通過對這個網(wǎng)站爬取時所遇到的數(shù)據(jù)加密問題進(jìn)行解析,從而獲取模擬真實(shí)的網(wǎng)絡(luò)請求[2]。這個技術(shù)會是大家探索網(wǎng)絡(luò)爬蟲的一個重要方向。
首先需要做的任務(wù)是利用爬蟲技術(shù)獲取翻譯前后的內(nèi)容。打開翻譯網(wǎng)站,在左邊輸入框中輸入‘man’英文字符,點(diǎn)擊“翻譯”按鈕,右邊翻譯框會輸出一個“男人”的譯文。這時打開F12開發(fā)者工具,選擇Network選項(xiàng),從中可以獲取到所有網(wǎng)絡(luò)發(fā)出的請求。怎樣找到哪一條是關(guān)鍵的請求呢?因?yàn)樽龅氖欠g工作,可以嘗試在Filter中輸入‘tran’的字樣進(jìn)行過濾操作,果然過濾到了一條translate的請求,這時候可以盲猜這條請求就是所需要的請求。
用requests庫編寫一個基礎(chǔ)的爬蟲代碼后,將請求頭中的cookie,header等信息放入爬蟲代碼,把參數(shù)一個一個地注釋,再進(jìn)行編譯并打印出狀態(tài)碼,從中可以看到,如果打印“500”則證明此參數(shù)影響了請求,則此參數(shù)是有價(jià)值的,這就是尋找有用參數(shù)的方法。通過尋找發(fā)現(xiàn)關(guān)鍵參數(shù)有“OUTFOX_SEARCH_USER_ID”“salt”“sign”3個參數(shù),通過多次請求比較,將會發(fā)現(xiàn)第一個參數(shù)在每次請求中都是不變的,所以最終確定兩個加密變化參數(shù)“salt”“sign”。
在開發(fā)者工具中搜索這兩個參數(shù),能找到一個js文件,這個就是要對其逆向的文件。在文件中查找參數(shù)名,可以發(fā)現(xiàn)12條相關(guān)數(shù)據(jù),從其中篩選出純參數(shù)數(shù)據(jù),在其位置打上斷點(diǎn)并進(jìn)行編譯。通過刷新頁面,可以發(fā)現(xiàn)下面這段代碼出現(xiàn)了問題(見圖1)。

圖1 斷點(diǎn)尋找加密方式
可以看出salt的值是變量i,在第8 371行中顯示,i的值為變量r+14位的隨機(jī)數(shù),再從8 370行中可以看出,變量r是一個時間戳,這就完美地解出了“salt”變量的組成。同理,從中能了解到,“sign”變量的組成是一個md5加密的數(shù)據(jù),提供的參數(shù)為要翻譯的字符串和“salt”值的拼接。參數(shù)的組成清晰又明朗,對下一步的模擬請求發(fā)送起著關(guān)鍵性的作用[3]。
了解到數(shù)據(jù)如何構(gòu)成之后,開始使用Python對整個請求發(fā)送進(jìn)行模擬。自己定義時間戳和隨機(jī)數(shù),拼接為“salt”和“sign”參數(shù),根據(jù)業(yè)務(wù)邏輯完成整個爬蟲流程,如下文代碼段。


得到模擬的請求參數(shù)之后,將參數(shù)嵌入爬蟲代碼中,并且根據(jù)網(wǎng)頁結(jié)構(gòu)找到翻譯結(jié)果的位置,從而進(jìn)行發(fā)送請求。實(shí)現(xiàn)方法如下文代碼段。


模擬請求發(fā)送后,使用重寫的爬蟲,得到翻譯框中翻譯的數(shù)據(jù),并且可以根據(jù)不同的語言得到不同的翻譯結(jié)果。例如輸入‘Long time no see’,得出結(jié)果“好久不見”。
JS逆向技術(shù)可謂是探索爬蟲領(lǐng)域的重要工具。通過對此翻譯網(wǎng)站的網(wǎng)頁結(jié)構(gòu)分析,找出隱藏在其中的加密參數(shù);通過斷點(diǎn)技術(shù),找出參數(shù)的加密方式。相比于傳統(tǒng)爬蟲,可謂是更上一層樓。希望這種技術(shù)可以為讀者開辟一種新的思路。JS逆向技術(shù)的道路很長,有些網(wǎng)站構(gòu)成復(fù)雜,僅僅拿到j(luò)s文件并不是所謂的全部。在短短一秒鐘內(nèi),執(zhí)行的代碼多達(dá)上萬行,這時就需要耐心分析,一步一個腳印,找出神秘之處,從而達(dá)到所需的目標(biāo)。如何從萬行代碼中突破重圍,如何將JS逆向技術(shù)加以改進(jìn),所有從事IT行業(yè)的人們都任重而道遠(yuǎn)。