硒不适用于为避免检测而修改的铬驱动程序



我问这个是因为我知道这个线程和这个线程,以及其他关于同一主题的线程,但是每个人在第一个线程中转发的解决方案不再有效。因此,请不要将其标记为已关闭,因为第一个线程存在。答案是从 2016 年开始的,您可以看到最近的评论遇到问题。

我正在使用硒来做一些轻便的网页抓取。我正在与之交互的一个站点清楚地检测到我的浏览器是自动化的(但奇怪的是,只要我也访问我所在地区以外的站点版本,它就只关心,但这既不在这里也不在那里(。

第一个线程中的解决方案建议从此处下载的chromedriver并进行修改。它说要摆脱对带有"$cdc$"的变量的提及。所以我做了以下几点。从该站点下载v2.41,解压缩。这个版本允许我通过br = webdriver.Chrome('./chromedriver')使用带有硒的Chrome,但存在自动化检测问题。所以,我cp这个来修改chromedriver。

在 chromedriver 修改中,我使用 vim 打开它并搜索$cdc。我发现一个与第 1934 行左右链接线程中的函数相似(但略有不同(的函数:

function getPageCache(opt_doc, opt_w3c) {
var doc = opt_doc || document;
var w3c = opt_w3c || false;
// var key = '$cdc_asdjflasutopfhvcZLmcfl_';
var key = 'xxxx_asdjflasutopfhvcZLmcfl_';
// var key = 'randomblahhh_';
if (w3c) {
if (!(key in doc))
doc[key] = new CacheWithUUID();
return doc[key];
} else {
if (!(key in doc))
doc[key] = new Cache();
return doc[key];
}
}

我尝试用随机的东西(randomblahhh_var(和只替换$cdc的前 4 个字符的东西替换这个变量,因为我在该线程的评论中看到两者都建议(我不知道变量的某些格式在这里是否重要。

两者都不起作用。我的意思是,当我尝试使用chromedriver-modified运行它时,网络驱动程序甚至不会启动:

>>> from selenium import webdriver
>>> br = webdriver.Chrome(executable_path='./chromedriver-modified')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/selenium/webdriver/chrome/webdriver.py", line 68, in __init__
self.service.start()
File "/usr/lib/python3/dist-packages/selenium/webdriver/common/service.py", line 96, in start
self.assert_process_still_running()
File "/usr/lib/python3/dist-packages/selenium/webdriver/common/service.py", line 109, in assert_process_still_running
% (self.path, return_code)
selenium.common.exceptions.WebDriverException: Message: Service ./chromedriver-modified unexpectedly exited. Status code was: -11

我在谷歌上搜索并弄清楚这个状态代码的含义时遇到了麻烦。事实上,我发现这个未回答的 reddit 线程具有相同的确切问题。

第一个线程也提到了$wdc变量,但我在 chromedriver 中没有提到它们。

只是为了抢占可能的建议:我几乎 100% 确信它检测到我正在使用自动浏览器,因为它是自动化的,而不是因为鼠标点击速度或其他任何东西。如果我使用硒启动浏览器,然后手动完成其余的工作,它仍然会导致问题。

编辑:我正在使用来自Ubuntu存储库的Chrome v68,google-chrome-stable。老实说,我不需要专门使用Chrome,但我找到的答案似乎围绕着它而不是Firefox。

edit2:最后一条评论 - 我在第一个链接线程中注意到有些人正在"重新编译":

对我来说,我

使用了chrome,所以,我所要做的就是确保 $cdc_ 不再作为文档变量存在,瞧(下载 Chrome Driver 源代码,修改 Chrome Driver 并重新编译 $cdc_ 以不同的名称。

我不确定这意味着什么 - 他们是否在重新编译Chrome本身?我所做的只是更改chromedriver文件中的变量。

删除

有多种可行的方法

1. 使用 chrome-developer-protocoll 和Page.removeScriptToEvaluateOnNewDocument就像在硒配置文件中一样

使用蟒蛇

# driver allready initialized here
driver.execute_cdp_cmd("Page.removeScriptToEvaluateOnNewDocument", {"identifier":"1"})

请参阅其他编程语言的文档

2. 使用 chrome-developer-protocoll 与Page.addScriptToEvaluateOnNewDocument使用来自未检测到的 chromedriver 的脚本

使用蟒蛇

# driver allready initialized here
js = """
let objectToInspect = window,
result = [];
while(objectToInspect !== null)
{ result = result.concat(Object.getOwnPropertyNames(objectToInspect));
objectToInspect = Object.getPrototypeOf(objectToInspect); }
result.forEach(p => p.match(/.+_.+_(Array|Promise|Symbol)/ig)
&&delete window[p]&&console.log('removed',p))
"""
driver.execute_cdp_cmd("Page.removeScriptToEvaluateOnNewDocument", {"source":js})

请注意,这个可能是可检测到的。

3.通过修补编译的chrome驱动程序。

这意味着只需删除 chromedriver-binary :) 中出现的所有cdc_*

有关Python脚本,请参阅 undetected_chromedriver/patcher.py

window.cdc_adoQpoasnfa76pfcZLmcfl_xxxxx 变量从每个新页面上的 chromedriver 添加,使用带有脚本Page.addScriptToEvaluateOnNewDocument的 chrome-developer-protocoll:

(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;
}) ();

幸运的是,它总是第一个脚本==>identifier="1"。这也是为什么1.方法有效。

它们似乎被硬编码到chromedriver中并用于制作shure,如果javascript属性被覆盖代码,chromedriver仍然可以工作

注意:我是Selenium-Profiles的开发者

除非您想构造具有某些功能的单个 chrome,否则无需再次重新编译它。尝试将$cdc_asdjflasutopfhvcZLmcfl_更改为$abc_asdjflasutopfhvcZLmcfl_.

请记住不要注意此行或将其更改为具有不同长度的其他变量名称。由于编译的文件对此很敏感,这可能会导致运行错误。

相关内容

  • 没有找到相关文章

最新更新