本次要采集的目標站點是 huishoushang.com/
,其數據詳情頁有公開的聯系電話,頁面采用前台 JS 加密,測試時原以為是字體反爬,結果不是。
隨機打開二手市場的某條數據,我們又看到了熟悉的手機號碼,然後快速的切換到了開發者工具的字體選項卡,結果什麼都沒有抓取到。
心理高興,以為碰到了新的字體加密形式,結果打臉了。
呈現效果如下所示,可以看到網頁源碼並沒有返回任何數字相關信息,但是有一個 decrypt
映入眼簾,這麼明顯的加密提示嗎?
由於加密信息在 HTML 元素的屬性中,所以直接檢索關鍵字 decrypt
即可。
首先將加密字符串提取一個,用作測試
(((((((((a01 % a03) % g02) % g08) % a08) % g04) % a09) % c07) % c00) % b09) % b08;
搜索之後得到如下解密代碼:
var str = $(th).attr("decrypt");if (str != null || str != undefined || str != '') { $(th).attr("decryptok", ""); // str = str.replace(/-/g, ",").replace(/ /g, ","); let strArray = str.split('%'); var newArray = []; for (var i = 0; i < strArray.length; i++) { let _rTemp = this.model.rArray.filter((a) => a.l == strArray[i]); if (_rTemp.length > 0) { newArray.push(_rTemp[0].v); } else { newArray.push(strArray[i]); } } $(th).html(newArray.join(''));
其中發現了一個關鍵點,即通過 str.split('%')
,截取了字符串,而且 this.model.rArray
也成為了問題的突破點。
在源碼中再次檢索 rArray
,又找到了其定義的位置。
/*數字解密 */var NumberDecrypt = { model: { rArray: [ { l: 'a01', v: '1' }, { l: 'b02', v: '1' }, { l: 'c03', v: '1' }, { l: 'f04', v: '1' }, { l: 'g01', v: '1' }, { l: 'a02', v: '2' }, { l: 'b03', v: '2' }, { l: 'c04', v: '2' }, { l: 'f05', v: '2' }, { l: 'g00', v: '2' },…… ], refreshTime: null, refreshCount: 0 },
此時相信你已經知道了解決方案,即加密字符串通過 %
切割,然後將得到的值,例如 a01
在轉換為數字 1
。
這次的案例沒有想到這麼簡單,希望大家可以輕松掌握。
本次采集的目標站點為 aHVhbmd5ZTg4.com
,首頁截圖如下所示。
在官網找到【黃x頁】選項卡,然後得到如下界面,其中涉及的信息如下,隨機找到一個公開數據。
在公司黃頁詳情頁可以查看到聯系人和聯系號碼。
這裡明顯看到手機字體與其它字體有所差異,通過開發者工具進行驗證之後,確定存在字體反爬。
保存字體文件,得到下述字體矢量圖。
結果字體的編碼是固定的英文,那這字體反爬的難度就變的極低了。
通過開發者工具可以找到字體文件在網頁源碼中,所以我們編寫一下相關提取代碼。
import reimport requestsimport base64from fontTools.ttLib import TTFonturl = 'https://b2b.huangye88.com/qiye1edkfp0964c7/'headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36'}res_text = requests.get(url=url, headers=headers).textba64 = re.findall('base64,(.*?)\"\)', res_text)[0]# print(ba64)data = base64.b64decode(ba64)with open('./fonts/519.woff', 'wb') as f: f.write(data)font = TTFont('./fonts/519.woff')font.saveXML('./fonts/519.xml')
得到字體之後,保存的 XML 文檔如下所示。
本案例已經結束。
你正在閱讀 【夢想橡皮擦】 的博客
閱讀完畢,可以點點小手贊一下
發現錯誤,直接評論區中指正吧
橡皮擦的第 680 篇原創博客