Puppeteer 系列踩坑日志—2—去掉自動化提示

在使用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é))
image-20200318111030912.png
  • 不知道大家使用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)了下面的目錄是這樣的:
image-20200318112851445.png
  • 解釋下非常有意思的幾個目錄:

    • .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到底從哪里來的?

image-20200318113507991.png

打開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í)排坑。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容