反爬虫中chrome无头浏览器的几种检测与绕过方式

chrome无头浏览器的几种检测方式

本文测试使用的chrome版本为 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3514.2 Safari/537.36

1.UserAgent检测

无头模式下的UA会带有HeadlessChrome关键字

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/70.0.3521.2 Safari/537.36

因此可以检查UA中的关键字

if (/HeadlessChrome/.test(navigator.userAgent)) {
  // headless...
}

2.Webdriver检测

无头模式下navigator.webdriver为true,因此可以进行如下检测。

// Webdriver Test
if (navigator.webdriver) {
  // headless...
}

为了绕过这个检测,重新设置该属性即可。

Object.defineProperty(navigator, 'webdriver', {
    get: () => false,
  });

建议通过原型删除该属性

delete navigator.__proto__.webdriver;

补充说明:大麦网或淘宝网的滑块验证码首先就会检测环境,
通常会利用sufei_data文件检测当前浏览器信息,其中检测webdriver代码如下

        function r() {
            return "$cdc_asdjflasutopfhvcZLmcfl_"in u || f.webdriver
        }
        
// 完整的检测代码,这个文件会经常升级        
// https://g.alicdn.com/secdev/sufei_data/3.6.8/index.js

因此在尝试拖动滑块的时候,先要修改该属性。不然如何修改路径都会提示错误,并要求重试。

document.$cdc_asdjflasutopfhvcZLmcfl_通常在使用selenium时会出现

3.chrome属性检测

在无头模式下window.chrome属性是undefined,而在正常有界面模式下,定义如下。

csi: ƒ ()
embeddedSearch: {searchBox: {…}, newTabPage: {…}}
loadTimes: ƒ ()
app: (...)
runtime: (...)
webstore: (...)
get app: ƒ nativeGetter()
set app: ƒ nativeSetter()
get runtime: ƒ nativeGetter()
set runtime: ƒ nativeSetter()
get webstore: ƒ nativeGetter()
set webstore: ƒ nativeSetter(

因此可以进行如下形式检测

if (!window.chrome || !window.chrome.runtime) {
  // headless...
}

绕过检测修改属性即可

 window.navigator.chrome = {
    runtime: {},
    // etc.
  };

4.Permissions检测

(async () => {
  const permissionStatus = await navigator.permissions.query({ name: 'notifications' });
  if(Notification.permission === 'denied' && permissionStatus.state === 'prompt') {
    // headless
  }
})();

无头模式下Notification.permission与navigator.permissions.query会返回相反的值。
因此绕过的方式如下。

// Pass the Permissions Test.
await page.evaluateOnNewDocument(() => {
  const originalQuery = window.navigator.permissions.query;
  return window.navigator.permissions.query = (parameters) => (
    parameters.name === 'notifications' ?
      Promise.resolve({ state: Notification.permission }) :
      originalQuery(parameters)
  );
});

5. Plugins长度检测

无头模式下navigator.plugins.length返回0

if (navigator.plugins.length === 0) {
  // headless
}

绕过方式如下

Object.defineProperty(navigator, 'plugins', {
    get: () => [1, 2, 3, 4, 5],
  });

注意:反爬除了检查长度,还会检查内容。如果你设置了长度,别忘了再设置内容。防止被反爬。

6.The Languages检测

navigator.languages检测方法

if (!navigator.languages || navigator.languages.length === 0) {
  // headless
}

绕过方法

  Object.defineProperty(navigator, 'languages', {
    get: () => ['en-US', 'en'],
  });

7.原文地址

https://intoli.com/blog/not-possible-to-block-chrome-headless/
https://intoli.com/blog/making-chrome-headless-undetectable/
https://github.com/infosimples/detect-headless
https://stackoverflow.com/questions/19877924/what-is-the-list-of-possible-values-for-navigator-platform-as-of-today

  • 14
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值