【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也一样。

六、成品

有能力的小伙伴建议自己把流程全部跑一边,编译个自己的指纹浏览器和驱动。
相关推荐
傻啦嘿哟8 分钟前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
大数据编程之光12 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
B站计算机毕业设计超人14 分钟前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
爪哇学长26 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
ExiFengs30 分钟前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj12345678931 分钟前
JDK1.8新增特性
java·开发语言
IT古董38 分钟前
【人工智能】Python在机器学习与人工智能中的应用
开发语言·人工智能·python·机器学习
繁依Fanyi42 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
Smartdaili China1 小时前
如何在 Microsoft Edge 中设置代理: 快速而简单的方法
前端·爬虫·安全·microsoft·edge·社交·动态住宅代理
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net