1 異常在識別中的使用
爬蟲在抓取瀏覽器數據時,常會用到代碼js代碼執行的工具。爲了識別,會利用函數棧來進行判斷。
如下是一個簡單的例子來描述問題。如果是在代碼執行器中執行就可以暴露出執行器方法名及行列等信息。因此將這些信息上報給後臺,與實際信息進行比較,分析判斷即可識別出是否是爬蟲。
(function(){
try{
throw new Error("test");
}catch(err) {
console.log(err.stack);
}
})();
VM754:5 Error: test
at <anonymous>:3:11
at <anonymous>:7:3
2 一些常見反異常識別
根據這個識別方式,如果依然通過代碼執行器抓取。顯然會考慮改變這些信息。常用的方式如下:
- 函數攔截:在字符串檢測識別繞過這篇中介紹了常見的攔截函數修改返回結果的形式。
- 重定義異常:此外我們將異常信息進行簡單改變,根據重定義異常的方式[1]來阻礙識別方判斷。
Object.defineProperty(Error,"stackTraceLimit",{
set:function(value) {
let obj = Error;
return (function(){
throw new UserError("異常信息");
})();
}
});
function UserError(message) {
this.message = message || '默認信息';
this.name = 'UserError';
}
UserError.prototype = new Error();
UserError.prototype.constructor = UserError;
UserError.prototype.stack = `VM696:1 Uncaught Error: 自定義異常
at <anonymous>:1:7`;
try {
Error.stackTraceLimit = 100
} catch(err) {
console.log(err.stack);
}
- 重定義執行代碼:通過執行器執行的方式,通常會傳入字符串代碼。這時候就可以考慮對代碼進行變換,使其拋出我們需要的異常信息。
3 總結
這些問題都可以歸結爲將一串信息改變爲我們期望的形式。因此關鍵就在於找到一個合適的修改點。可以是函數攔截、代碼修改、甚至修改瀏覽器代碼。在拋出過程中有些信息是動態變化的,因此可以結合一些動態請求,配合調整輸出即可。
4 參考
[1]錯誤處理機制,https://javascript.ruanyifeng.com/grammar/error.html#toc0