來(lái)了!最完美方案!Selenium模擬瀏覽器如何正確隱藏特征

在前天的公眾號(hào)文章《別去送死了。Selenium 與 Puppeteer 能被網(wǎng)站探測(cè)的幾十個(gè)特征》中,我們提到目前網(wǎng)上的反檢測(cè)方法幾乎都是掩耳盜鈴,因?yàn)槟M瀏覽器有幾十個(gè)特征可以被檢測(cè),僅僅隱藏 webdriver 這一個(gè)值是沒(méi)有任何意義的。
今天我們就來(lái)說(shuō)說(shuō)應(yīng)該如何正確解決這個(gè)問(wèn)題。我們首先給出解決方案。然后再說(shuō)明這個(gè)解決方案,我是通過(guò)什么方式找到的。
解決這個(gè)問(wèn)題的關(guān)鍵,就是一個(gè) js 文件,叫做stealth.min.js。稍后我會(huì)說(shuō)明如何生成這個(gè)文件。
我們需要設(shè)定,讓 Selenium 或者 Pyppeteer 在打開(kāi)任何頁(yè)面之前,先運(yùn)行這個(gè) Js 文件。具體的做法和原理,大家可以參考我這兩篇文章:
(最新版)如何正確移除Selenium中的 window.navigator.webdriver
(最新版)如何正確移除 Pyppeteer 中的window.navigator.webdriver
這里,我以 Selenium 為例來(lái)說(shuō)明如何操作,我們編寫(xiě)如下代碼:
import?time
from?selenium.webdriver?import?Chrome
from?selenium.webdriver.chrome.options?import?Options
chrome_options?=?Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument('user-agent=Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_15_7)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/86.0.4240.198?Safari/537.36')
driver?=?Chrome('./chromedriver',?options=chrome_options)
with?open('/Users/kingname/test_pyppeteer/stealth.min.js')?as?f:
????js?=?f.read()
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",?{
??"source":?js
})
driver.get('https://bot.sannysoft.com/')
time.sleep(5)
driver.save_screenshot('walkaround.png')
#?你可以保存源代碼為?html?再雙擊打開(kāi),查看完整結(jié)果
source?=?driver.page_source
with?open('result.html',?'w')?as?f:
????f.write(source)
運(yùn)行截圖如下:

可以看到,雖然我使用的是無(wú)頭模式,但是能夠被識(shí)別的特征都被成功隱藏。大家還可以雙擊打開(kāi)保存下來(lái)的 html 文件,看看是不是結(jié)果跟普通瀏覽器幾乎一樣。
如果你使用的是 Pyppeteer,那么可以根據(jù)我上面文章中給出的方法,試著加載一下這個(gè) js 文件,看看是不是也能成功隱藏特征。
那么,這個(gè)stealth.min.js文件是怎么來(lái)的呢?這就要說(shuō)到puppeteer了。我們知道,Python 版本的pyppeteer已經(jīng)很久沒(méi)有人維護(hù)了,但是Node.js 版本的 puppeteer持續(xù)有人維護(hù),并且在持續(xù)更新,生態(tài)也越來(lái)越好。
有開(kāi)發(fā)者給 puppeteer 寫(xiě)了一套插件,叫做puppeteer-extra。其中,就有一個(gè)插件叫做puppeteer-extra-plugin-stealth[1]。這個(gè)東西,就來(lái)專門用來(lái)讓 puppeteer 隱藏模擬瀏覽器的指紋特征。
這個(gè)東西是專門給 puppeteer 用的。所以,如果你使用的是 puppeteer,那么你可以根據(jù)它的 Readme說(shuō)明,直接使用。
那么,我們用 Python 的人怎么辦呢?實(shí)際上也有辦法。就是把其中的隱藏特征的腳本提取出來(lái),做成一個(gè)單獨(dú)的 js 文件。然后讓 Selenium 或者 Pyppeteer 在打開(kāi)任意網(wǎng)頁(yè)之前,先運(yùn)行一下這個(gè) js 文件里面的內(nèi)容。
puppeteer-extra-plugin-stealth的作者還寫(xiě)了另外一個(gè)工具,叫做extract-stealth-evasions[2]。這個(gè)東西就是用來(lái)生成stealth.min.js文件的。
如果你在國(guó)外,并且網(wǎng)速足夠快的話。那么你根據(jù)它的 Readme,首先安裝 Node.js,然后安裝 Npm,接著運(yùn)行如下命令:
npx?extract-stealth-evasions
就會(huì)在你執(zhí)行命令的文件夾下面生成一個(gè)stealth.min.js文件。然后你就可以正常使用了。
如果你在國(guó)內(nèi),那么執(zhí)行這個(gè)命令的過(guò)程中,會(huì)有一個(gè)下載 Chromium 的過(guò)程,速度非常慢,雖然只有130MB,但是可能會(huì)下載好幾個(gè)小時(shí)。
此時(shí),你需要把它的package.json和index.js兩個(gè)文件保存到本地。然后打開(kāi)package.json文件,修改其中的dependencies這一項(xiàng),把里面的puppeteer改成puppeteer-core,如下圖所示:

然后修改index.js,給.launch()函數(shù)增加一個(gè)參數(shù)executablePath,指向你電腦上的 Chrome 瀏覽器,如下圖所示:

修改完成以后。首先執(zhí)行yarn install安裝依賴包。然后執(zhí)行node index.js運(yùn)行程序。1秒鐘以后就會(huì)生成stealth.min.js了。
如果你對(duì) Node.js 的工具鏈不熟悉,不知道如何使用。那么你可以關(guān)注公眾號(hào)未聞 Code,回復(fù)stealth獲取這個(gè) js 文件。
參考資料
puppeteer-extra-plugin-stealth: https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth
[2]extract-stealth-evasions: https://github.com/berstend/puppeteer-extra/tree/master/packages/extract-stealth-evasions
-END-
掃碼添加早小起
1.?回復(fù)「進(jìn)群」進(jìn)入Python技術(shù)交流群
2. 回復(fù)「Python」獲得Python技術(shù)圖書(shū)
3. 回復(fù)「習(xí)題」領(lǐng)取Python數(shù)據(jù)處理200題
