你以為的萬(wàn)能爬蟲方法,其實(shí)一行代碼就能識(shí)別!
在以前的公眾號(hào)中,我提到Selenium/Puppeteer/Pyppeteer有很多特征可以被網(wǎng)站檢測(cè)到。于是,有些同學(xué)想到了另一個(gè)方法,就是自己寫一個(gè)Chrome插件,在網(wǎng)站打開的時(shí)候,注入到頁(yè)面中,然后通過(guò)這個(gè)注入的JavaScript代碼來(lái)操作頁(yè)面,獲取數(shù)據(jù)。
這個(gè)方法理論上說(shuō)是萬(wàn)能的,因?yàn)樽⑷氲腏avaScript能夠獲取當(dāng)前Dom樹,任何接口簽名都無(wú)法攔截到自己注入的JavaScript代碼,如下圖所示:
而Chrome插件訪問(wèn)自己的服務(wù)器后端是沒(méi)有跨域問(wèn)題的,完全可以讓插件獲取到數(shù)據(jù)以后,發(fā)送給自己的服務(wù)器,這樣就可以把數(shù)據(jù)收入囊中了。
你還可以通過(guò)JavaScript自動(dòng)點(diǎn)擊按鈕,實(shí)現(xiàn)自動(dòng)翻頁(yè)。所以你只需要把網(wǎng)頁(yè)打開,啟動(dòng)插件,然后他就能自動(dòng)刷新,自動(dòng)獲取數(shù)據(jù)了。
這個(gè)方法看起來(lái)非常萬(wàn)能,而且無(wú)法被防御……
事實(shí)真的是這樣嗎?我寫了一個(gè)Demo來(lái)做測(cè)試。Demo頁(yè)面長(zhǎng)下面這樣:
當(dāng)我手動(dòng)點(diǎn)擊點(diǎn)擊我按鈕的時(shí)候,會(huì)彈出一個(gè)框:
現(xiàn)在,我使用JavaScript來(lái)選擇這個(gè)按鈕,然后點(diǎn)擊它:
為什么網(wǎng)站知道我在用JavaScript點(diǎn)擊了按鈕呢?其實(shí)只要我給你看這個(gè)頁(yè)面的HTML,你就知道了:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Event</title>
</head>
<body>
<div id="app">
<template v-if="spider">
<div>你這個(gè)狗爬蟲</div>
</template>
<template v-else>
<button v-on:click="check">點(diǎn)擊我</button>
</template>
</div>
<script src="./vue.min.js"></script>
<script>
var example2 = new Vue({
el: '#app',
data: {
spider: false
},
methods: {
check: function (event) {
if (event.isTrusted) {
alert('主人你好,歡迎回家!')
} else {
this.spider = true
}
}
}
})
</script>
</body>
</html>
關(guān)鍵的點(diǎn)就是這個(gè)event.isTrusted。它是瀏覽器的一個(gè)功能,如果這個(gè)事件是人通過(guò)鼠標(biāo)點(diǎn)擊的,那么它是true。如果事件是通過(guò)JavaScript觸發(fā)的,那么它是false。
關(guān)于這個(gè)屬性,你可以查看Event.isTrusted - Web API 接口參考 | MDN[1]。這個(gè)例子里面,我用的是Vue來(lái)操作頁(yè)面,但實(shí)際上event是瀏覽器的特性,使用原生JavaScript也可以實(shí)現(xiàn):
document.querySelector("button").addEventListener("click", function( event ) {
if (event.isTrusted) {
alert('主人你好,歡迎回家!')
} else {
this.spider = true
}
}, false);
那么如何繞過(guò)這個(gè)event.isTrusted呢?其實(shí)很簡(jiǎn)單,你使用Selenium/Puppeteer,天然就能繞過(guò)它。
看到這里,大家肯定發(fā)現(xiàn)一個(gè)很好笑的問(wèn)題,Selenium/Puppeteer不能解決的問(wèn)題,用JavaScript輕松就能解決。但JavaScript解決不了的問(wèn)題,用Selenium/Puppeteer又完全沒(méi)有問(wèn)題。
這就像是貓吃老鼠,老虎吃貓,大象吃老虎,但是老鼠可以吃大象。寸有所長(zhǎng),必有所短,寸有所短,也可能有所長(zhǎng)。
參考文獻(xiàn)
[1] Event.isTrusted - Web API 接口參考 | MDN: https://developer.mozilla.org/zh-CN/docs/Web/API/Event/isTrusted
本文轉(zhuǎn)載自微信公眾號(hào)「未聞Code」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系未聞Code公眾號(hào)。