【chromedriver编译-绕过selenium机器人检测】

复制代码
有小伙伴说使用selenium没能绕过机器人检测,盘他。
selenium机器人检测有2种,一是cdp检测,二是webdriver特征检测。cdp检测前面的博客已写过,这里就提下webdriver特征检测。

一、selenium简介

复制代码
Selenium 是一个强大的工具,用于Web浏览器自动化,更常被用于爬虫。
但selenium需要通过webdriver来驱动chrome,每次运行selenium时,都要先找到对应版本的chromedriver.exe。
chromedriver自动化会对浏览器的部分属性进行修改,非常容易被识别为机器人。
pypeeteer却没有这种烦恼,它不需要中间驱动,所以还是建议大家使用pyppeteer。但如果你已经写了上万行selenium代码了,那还是编译一个驱动吧。

二、机器人识别网站

1.https://www.browserscan.net/bot-detection

2.https://fingerprintjs.github.io/BotD/main/

复制代码
很明显,常规网站都能检测到selenium机器人。

三、检测原理

1:cdp检测,

cdp检测的原理一般是利用console.debug()函数来实现,当你打开consle控制台时,console.debug()才会真正的被调用。

一旦console.debug()函数被触发,我们就可以认定你打开了F12控制台。

bash 复制代码
<!DOCTYPE html>
<html>

<head>
	<title>Detect Chrome DevTools Protocol</title>
	<script>
		function genNum(e) {
			return 1000 * e.Math.random() | 0;
		}
		function catchCDP(e) {
			if (e.chrome) {
				var rng1 = 0;
				var rng2 = 1;
				var acc = rng1;
				var result = false;
				try {
					var errObj = new e.Error();
					var propertyDesc = {
						configurable: false,
						enumerable: false,
						get: function () {
							acc += rng2;
							return '';
						}
					};
					Object.defineProperty(errObj, "stack", propertyDesc);
					console.debug(errObj);
					errObj.stack;
					if (rng1 + rng2 != acc) {
						result = true;
					}
				} catch {

				}
				return result;
			}
		}
		function isCDPOn() {
			if(!window)
				return;
			const el = document.querySelector('span#status');
			if(!el)
				return;
			el.innerText = catchCDP(window) ? "yes":"no";
		}
		function init() {
			isCDPOn();
			setInterval(isCDPOn, 100);
		}
		document.addEventListener("DOMContentLoaded", init);
	</script>
</head>

<body>
	<p>CDP Detected: <span id="status">-</span></p>
</body>

</html>

2 :webdriver特征检测

复制代码
将下面的js代码复制粘贴进F12控制台:
bash 复制代码
// 定义正则表达式
let regex = /^([a-z]){3}_.*_(Array|Promise|Symbol|JSON|Object|Proxy)$/;
// 获取window对象的所有属性名称
let allProps = Object.getOwnPropertyNames(window);
// 过滤出符合正则表达式的属性名称
let filteredProps = allProps.filter(prop => regex.test(prop));
// 输出匹配的属性名
console.log(filteredProps);

在这里插入图片描述

复制代码
注意:这就是这2个站检测selenium机器人的核心逻辑。

四、编译crhomedriver.exe

打开chromium源码文件:\chrome\test\chromedriver\chrome\devtools_client_impl.cc

1 绕过cdp检测

找到下面的代码

bash 复制代码
void V8Console::Debug(const v8::debug::ConsoleCallArguments& info,
                      const v8::debug::ConsoleContext& consoleContext) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.inspector"), "V8Console::Debug");
  ConsoleHelper(info, consoleContext, m_inspector)
      .reportCall(ConsoleAPIType::kDebug);
}

替换为

bash 复制代码
void V8Console::Debug(const v8::debug::ConsoleCallArguments& info,
                      const v8::debug::ConsoleContext& consoleContext) {
  //TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.inspector"), "V8Console::Debug");
  //ConsoleHelper(info, consoleContext, m_inspector)
  //    .reportCall(ConsoleAPIType::kDebug);
}

2 绕过webdriver特征检测

找到下面的代码

bash 复制代码
std::string script =
        "(function () {"
        "window.cdc_adoQpoasnfa76pfcZLmcfl_Array = window.Array;"
        "window.cdc_adoQpoasnfa76pfcZLmcfl_Object = window.Object;"
        "window.cdc_adoQpoasnfa76pfcZLmcfl_Promise = window.Promise;"
        "window.cdc_adoQpoasnfa76pfcZLmcfl_Proxy = window.Proxy;"
        "window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol = window.Symbol;"
        "window.cdc_adoQpoasnfa76pfcZLmcfl_JSON = window.JSON;"
        "}) ();";
    params.Set("source", script);

替换为:

bash 复制代码
std::string script =
        "(function () {"
        //"window.cdc_adoQpoasnfa76pfcZLmcfl_Array = window.Array;"
        //"window.cdc_adoQpoasnfa76pfcZLmcfl_Object = window.Object;"
        //"window.cdc_adoQpoasnfa76pfcZLmcfl_Promise = window.Promise;"
        //"window.cdc_adoQpoasnfa76pfcZLmcfl_Proxy = window.Proxy;"
        //"window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol = window.Symbol;"
        //"window.cdc_adoQpoasnfa76pfcZLmcfl_JSON = window.JSON;"
        "}) ();";
    params.Set("source", script);

3.编译:

ninja -C out/Default chromedriver

复制代码
注意:编译完后,会在out/Default目录下生成一个chromedriver.exe文件,这就是驱动。

五、验证

复制代码
将生成的chromedriver.exe拿过来,运行下面的python代码:
bash 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

# 指定chromedriver的路径
s = Service(r"chromedriver.exe")  # 请将这里替换为你的chromedriver路径

# 初始化Chrome选项
chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = r"C:\Users\Administrator\AppData\Local\Chromium\Application\chrome.exe"  # 请将这里替换为你的Chrome浏览器路径
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--fingerprints=11111111")

# 使用Service对象初始化driver
driver = webdriver.Chrome(service=s, options=chrome_options)
driver.delete_all_cookies()

# driver.get("https://www.browserscan.net/bot-detection")
driver.get("https://fingerprintjs.github.io/BotD/main/")
time.sleep(99999)

指定chromedriver的路径

s = Service(r"chromedriver.exe") # 请将这里替换为你的chromedriver路径

初始化Chrome选项

chrome_options = webdriver.ChromeOptions()

chrome_options.binary_location = r"C:\Users\Administrator\AppData\Local\Chromium\Application\chrome.exe" # 请将这里替换为你的Chrome浏览器路径

chrome_options.add_argument("--no-sandbox")

chrome_options.add_argument("--fingerprints=11111111")

使用Service对象初始化driver

driver = webdriver.Chrome(service=s, options=chrome_options)

driver.delete_all_cookies()

driver.get("https://www.browserscan.net/bot-detection")

driver.get("https://fingerprintjs.github.io/BotD/main/")

time.sleep(99999)

复制代码
可以看到,依旧是自动化控制,官网却已经检测不到了。browserscan也一样。

六、成品

复制代码
有能力的小伙伴建议自己把流程全部跑一边,编译个自己的指纹浏览器和驱动。
相关推荐
郁大锤19 小时前
在 Windows 下安装与快速上手 Wireshark(抓包工具)
windows·测试工具·wireshark
这周也會开心19 小时前
云服务器安装JDK、Tomcat、MySQL
java·服务器·tomcat
hrrrrb20 小时前
【Spring Security】Spring Security 概念
java·数据库·spring
小信丶20 小时前
Spring 中解决 “Could not autowire. There is more than one bean of type“ 错误
java·spring
周杰伦_Jay21 小时前
【Java虚拟机(JVM)全面解析】从原理到面试实战、JVM故障处理、类加载、内存区域、垃圾回收
java·jvm
晓风残月淡21 小时前
JVM字节码与类的加载(二):类加载器
jvm·python·php
西柚小萌新1 天前
【深入浅出PyTorch】--上采样+下采样
人工智能·pytorch·python
2501_915909061 天前
tcpdump 抓包数据分析实战,命令、过滤、常见故障定位与真机补充流程
网络·测试工具·ios·小程序·uni-app·iphone·tcpdump
程序员小凯1 天前
Spring Boot测试框架详解
java·spring boot·后端
豐儀麟阁贵1 天前
基本数据类型
java·算法