在使用puppeteer自動化的過程中,經(jīng)常出現(xiàn)一個自動化提示:正在被自動化測試。而這個提示不僅僅有這個作用,它還能讓很多網(wǎng)站識別出來,你是在使用爬蟲訪問,從而采取了相應(yīng)的反制措施,怎么反制,你懂得。今天我們就來探討下這個問題!
基礎(chǔ):chrome啟動參數(shù)的理解
- 關(guān)于啟動參數(shù),其實網(wǎng)上已經(jīng)有非常多的列表了,我這里也隆重推薦一個大家都認(rèn)為比較全面的清單:https://peter.sh/experiments/chromium-command-line-switches/
- 拿著清單,我們現(xiàn)在來理解下,什么叫做chrome啟動參數(shù)?(已經(jīng)理解的,或者著急看解決方式可以跳過這段,直接看后面,這里詳細(xì)講原理別嫌啰嗦,這里照顧不了解的同學(xué))

不知道大家使用chrome瀏覽器的時候,有沒有注意到右上角的“用戶”選項,當(dāng)我們新建一個用戶出來的時候,其實桌面自動為我們生成了一個快捷方式。
所謂用戶:就是理解為谷歌的分身,另外一個完全與現(xiàn)在不相關(guān)的chrome被打開。例如多開帳號等等操作。
我們打開這個快捷方式,看下里面究竟是怎么回事,屬性,查看目標(biāo)那一欄,我們可以看到一串這樣的東西:"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 5"
-
--profile-directory ? Selects directory of profile to associate with the first browser launched. ? 配置文件目錄 選擇要與啟動的第一個瀏覽器關(guān)聯(lián)的配置文件目錄。 前面那段路徑其實可以省略,就是大家chrome安裝路徑,主要是后面這段是什么鬼?其實這就是我們說的命令行參數(shù),我們打開前面peter給出的chrome啟動參數(shù)列表,搜索到這一行的解釋: Selects directory of profile to associate with the first browser launched. 意思是:選擇要與啟動的第一個瀏覽器關(guān)聯(lián)的配置文件目錄。那么也就理解了,其實chrome命令行參數(shù),就是做類似于改變chrome啟動操作的一些事情,例如:配置用戶目錄,更改瀏覽器窗口大小,關(guān)閉瀏覽器跨域,改變?yōu)g覽器渲染進程等等。
所以我們關(guān)心的去掉自動化提示這個問題,其實就是在這里可以找到答案,我們繼續(xù)往后翻peter給的列表,翻到這個參數(shù):
-
--enable-automation ? Enable indication that browser is controlled by automation. ? 自動化測試提示參數(shù) 啟用瀏覽器由自動化控制的指示。 好家伙,我們現(xiàn)在看到的這個,就是元兇,那么你可能會有疑問:我代碼里明明啥都沒加啊,為啥還會有?
莫急,我們先想想npm包本身呢?是不是問題出在了這里?由此,我們引入了第一個解決方法。
解決方案1:修改puppeteer npm包源碼(不推薦)
- 首先看到標(biāo)題你就知道了,不推薦這個做法,因為破壞了源碼,以后包升級還是會有問題。但是還是要講一下,因為了解原理,可以舉一反三。
- 我們看源碼首先得前往
項目\node_modules\puppeteer目錄下去看,我們發(fā)現(xiàn)了下面的目錄是這樣的:

-
解釋下非常有意思的幾個目錄:
- .local-chromium:當(dāng)年剛出來的時候,大家用puppeteer都得搭XX,就是因為這個玩意下載不下來導(dǎo)致的,很多人就放棄了。其實這里面就放了一個chromium,平時puppeteer啟動的時候,默認(rèn)就是調(diào)用這個瀏覽器。這個瀏覽器的好處是,免安裝,隨時可用,更新快,功能激進(并沒發(fā)現(xiàn)激進啥,我偶爾存u盤里方便在一些不那么年輕的電腦上 用chrome瀏覽網(wǎng)頁)
- index.js
- lib
首先在index.js里面看到這段
const Puppeteer = require('./lib/Puppeteer');,我們根據(jù)這個往下找puppeteer到底從哪里來的?

打開puppeteer.js,繼續(xù)看下去,第一行 const Launcher = require('./Launcher'); 就引起了我們的懷疑,因為下面的代碼里面 都有options跟它息息相關(guān),本著不放過一個的精神,我們打開查看,粗略的瀏覽了一下,貌似沒有什么問題?可是別急,繼續(xù)往下看,我們發(fā)現(xiàn)了一堆有意思的東西:
defaultArgs(options = {}) {
const chromeArguments = [
'--disable-background-networking',
'--enable-features=NetworkService,NetworkServiceInProcess',
'--disable-background-timer-throttling',
'--disable-backgrounding-occluded-windows',
'--disable-breakpad',
'--disable-client-side-phishing-detection',
'--disable-component-extensions-with-background-pages',
'--disable-default-apps',
'--disable-dev-shm-usage',
'--disable-extensions',
'--disable-features=TranslateUI',
'--disable-hang-monitor',
'--disable-ipc-flooding-protection',
'--disable-popup-blocking',
'--disable-prompt-on-repost',
'--disable-renderer-backgrounding',
'--disable-sync',
'--force-color-profile=srgb',
'--metrics-recording-only',
'--no-first-run',
'--enable-automation',
'--password-store=basic',
'--use-mock-keychain',
];
const {
devtools = false,
headless = !devtools,
args = [],
userDataDir = null
} = options;
if (userDataDir)
chromeArguments.push(`--user-data-dir=${userDataDir}`);
if (devtools)
chromeArguments.push('--auto-open-devtools-for-tabs');
if (headless) {
chromeArguments.push(
'--headless',
'--hide-scrollbars',
'--mute-audio'
);
}
if (args.every(arg => arg.startsWith('-')))
chromeArguments.push('about:blank');
chromeArguments.push(...args);
return chromeArguments;
}
驚不驚喜,意不意外?看到名字就知道了:defaultArgs,也就是在你啟動puppeteer的時候,不論如何,它都會給你來一個這樣的參數(shù)列表追加進去,因此我們在使用puppeteer的時候,試著這里的:--enable-automation 刪除,再重新跑一遍puppeteer,那個煩人的提示就不見了。(這個時候再試試去登陸那些反爬蟲網(wǎng)站,so easy?。?/p>
注意坑:這里我遇到過一個令我羞愧難當(dāng)?shù)膯栴},我曾經(jīng)十分自信的跟同事說:用這個方法肯定沒問題,可是當(dāng)去掉了,并且執(zhí)行了我以上這些操作,提示是沒了,但是還是被反爬蟲網(wǎng)站發(fā)現(xiàn)了!我真是見了鬼了!打臉來的如此之快!
解決坑:最后經(jīng)過不斷的排摸問題,發(fā)現(xiàn)原來是chromium的問題,換成chrome或者是其他版本的chromium就沒問題了,所以當(dāng)大家遇到類似問題,可以嘗試著切換下版本或者是chrome。這也印證了為什么谷歌官網(wǎng)chromium提醒我們,不穩(wěn)定。官方大佬說的話,真的不能輕視每一句??!
解決方案2:官方方案(推薦)
這里我們來講解下解決方案,有句名言:當(dāng)你遇到問題,先去看官方文檔??赐耆绻€不知道怎么解決?請熟讀并背誦文檔!
其實官方文檔里面已經(jīng)給出過解決方法(但是官方文檔往往不太喜歡直白的告訴你),我們來回憶一下文檔里說的,launch的時候有個參數(shù):
ignoreDefaultArgs官方原話在這里: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions
這個屬性可以過濾掉本身默認(rèn)提供給你的參數(shù),接收的類型:
<boolean|Array<string>>我們需要將過濾的參數(shù)寫成['參數(shù)1','參數(shù)2','參數(shù)3'...],加上這個,就完美解決了問題!-
照顧一下連代碼都懶得敲的同學(xué):
puppeteer.launch({ ... ignoreDefaultArgs:['--enable-automation'] ... })再去測試下,就沒有那個測試提醒了。
- 如有遇到其他問題,評論下方可以聯(lián)系我,共同學(xué)習(xí)排坑。