Aja*_*nth 10 java selenium webdriver selenium-webdriver webdriver-w3c-spec
我正在尝试使用selenium和chrome在网站中自动执行一项非常基本的任务,但不知何故,网站检测到chrome由硒驱动并阻止每个请求.我怀疑该网站依赖于一个暴露的DOM变量,如/sf/answers/2933311741/来检测selenium驱动的浏览器.
我的问题是,有没有办法让navigator.webdriver标志为假?我愿意在修改之后尝试重新编译硒源,但我似乎无法在存储库中的任何地方找到NavigatorAutomationInformation源https://github.com/SeleniumHQ/selenium
任何帮助深表感谢
PS:我还从https://w3c.github.io/webdriver/#interface尝试了以下内容
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
Run Code Online (Sandbox Code Playgroud)
但它只在初始页面加载后更新属性.我认为该网站在我的脚本执行之前检测到该变量.
010*_*101 64
铬驱动程序:
终于用一个简单的标志发现了这个简单的解决方案!:)
--disable-blink-features=AutomationControlled
Run Code Online (Sandbox Code Playgroud)
navigator.webdriver=true将不再显示该标志集。
有关您可以禁用的内容列表,请在此处查看
小智 27
请勿使用 cdp 命令更改 webdriver 值,因为它会导致不一致,稍后可用于检测 webdriver。使用下面的代码,这将删除 webdriver 的任何痕迹。
options.add_argument("--disable-blink-features")
options.add_argument("--disable-blink-features=AutomationControlled")
Run Code Online (Sandbox Code Playgroud)
小智 16
要排除 2019 年 11 月 6 日更新的最高投票答案中提到的启用自动化开关的集合,截至 2020 年 4 月不再有效。相反,我收到以下错误:
ERROR:broker_win.cc(55)] Error reading broker pipe: The pipe has been ended. (0x6D)
Run Code Online (Sandbox Code Playgroud)
以下是截至 2020 年 4 月 6 日 Chrome 80 的运行情况。
之前(在 Chrome 控制台窗口中):
> navigator.webdriver
true
Run Code Online (Sandbox Code Playgroud)
蟒蛇示例:
options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features")
options.add_argument("--disable-blink-features=AutomationControlled")
Run Code Online (Sandbox Code Playgroud)
之后(在 Chrome 控制台窗口中):
> navigator.webdriver
undefined
Run Code Online (Sandbox Code Playgroud)
som*_*lse 14
之前(在浏览器控制台窗口中):
> navigator.webdriver
true
Run Code Online (Sandbox Code Playgroud)
变化(硒):
// C#
var options = new ChromeOptions();
options.AddExcludedArguments(new List<string>() { "enable-automation" });
// Python
options.add_experimental_option("excludeSwitches", ['enable-automation'])
Run Code Online (Sandbox Code Playgroud)
之后(在浏览器控制台窗口中):
> navigator.webdriver
undefined
Run Code Online (Sandbox Code Playgroud)
此功能不适用于ChromeDriver 79.0.3945.16及更高版本。在此处查看发行说明
pgu*_*rio 14
现在,您可以使用 cdp 命令完成此操作:
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
driver.get(some_url)
Run Code Online (Sandbox Code Playgroud)
顺便说一句,你想退货undefined
,false
是一个死赠品。
hld*_*dev 11
由于这个问题与硒有关,跨浏览器的覆盖解决方案navigator.webdriver
是有用的。这可以通过在目标页面的任何 JS 运行之前修补浏览器环境来完成,但不幸的是,除了 chromium 之外,没有其他浏览器允许在文档加载之后和任何其他 JS 运行之前评估任意 JavaScript 代码(firefox 与 Remote Protocol很接近)。
在修补之前,我们需要检查默认浏览器环境是什么样子的。在更改属性之前,我们可以使用以下命令查看它的默认定义Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor(navigator, \'webdriver\');\n// undefined\n
Run Code Online (Sandbox Code Playgroud)\n因此,通过这个快速测试,我们可以看到webdriver
属性未在navigator
. 它实际上定义在Navigator.prototype
:
Object.getOwnPropertyDescriptor(Navigator.prototype, \'webdriver\');\n// {set: undefined, enumerable: true, configurable: true, get: \xc6\x92}\n
Run Code Online (Sandbox Code Playgroud)\n更改拥有该属性的对象的属性非常重要,否则可能会发生以下情况:
\nnavigator.webdriver; // true if webdriver controlled, false otherwise\n// this lazy patch is commonly found on the internet, it does not even set the right value\nObject.defineProperty(navigator, \'webdriver\', {\n get: () => undefined\n});\nnavigator.webdriver; // undefined\nObject.getOwnPropertyDescriptor(Navigator.prototype, \'webdriver\').get.apply(navigator);\n// true\n
Run Code Online (Sandbox Code Playgroud)\n一个不太幼稚的补丁会首先针对正确的对象并使用正确的属性定义,但深入挖掘我们可以发现更多的不一致之处:
\nconst defaultGetter = Object.getOwnPropertyDescriptor(Navigator.prototype, \'webdriver\').get;\ndefaultGetter.toString();\n// "function get webdriver() { [native code] }"\nObject.defineProperty(Navigator.prototype, \'webdriver\', {\n set: undefined,\n enumerable: true,\n configurable: true,\n get: () => false\n});\nconst patchedGetter = Object.getOwnPropertyDescriptor(Navigator.prototype, \'webdriver\').get;\npatchedGetter.toString();\n// "() => false"\n
Run Code Online (Sandbox Code Playgroud)\n完美的补丁不会留下任何痕迹,如果我们能够拦截对它的调用并更改返回值,而不是替换 getter 函数,那就太好了。JavaScript 通过Proxy apply
handler对此提供本机支持:
const defaultGetter = Object.getOwnPropertyDescriptor(Navigator.prototype, \'webdriver\').get;\ndefaultGetter.apply(navigator); // true\ndefaultGetter.toString();\n// "function get webdriver() { [native code] }"\nObject.defineProperty(Navigator.prototype, \'webdriver\', {\n set: undefined,\n enumerable: true,\n configurable: true,\n get: new Proxy(defaultGetter, { apply: (target, thisArg, args) => {\n // emulate getter call validation\n Reflect.apply(target, thisArg, args);\n return false;\n }})\n});\nconst patchedGetter = Object.getOwnPropertyDescriptor(Navigator.prototype, \'webdriver\').get;\npatchedGetter.apply(navigator); // false\npatchedGetter.toString();\n// "function () { [native code] }"\n
Run Code Online (Sandbox Code Playgroud)\n现在唯一不一致的是函数名称,不幸的是,无法覆盖本机表示中显示的函数名称toString()
。{ [native code] }
但即便如此,它也可以传递通用正则表达式,通过查找其字符串表示形式的末尾来搜索欺骗性的浏览器本机函数。要消除这种不一致,您可以修补Function.prototype.toString
并使其为您修补的所有本机函数返回有效的本机字符串表示形式。
总而言之,在 Selenium 中它可以应用于:
\nchrome.execute_cdp_cmd(\'Page.addScriptToEvaluateOnNewDocument\', {\'source\': """\n Object.defineProperty(Navigator.prototype, \'webdriver\', {\n set: undefined,\n enumerable: true,\n configurable: true,\n get: new Proxy(\n Object.getOwnPropertyDescriptor(Navigator.prototype, \'webdriver\').get,\n { apply: (target, thisArg, args) => {\n // emulate getter call validation\n Reflect.apply(target, thisArg, args);\n return false;\n }}\n )\n });\n"""})\n
Run Code Online (Sandbox Code Playgroud)\nplaywright项目维护了 Firefox 和 WebKit 的一个分支,以添加浏览器自动化功能,其中之一相当于,但没有通信协议的 Python 实现,但可以从头开始实现。Page.addScriptToEvaluateOnNewDocument
python 的简单破解:
options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")
Run Code Online (Sandbox Code Playgroud)
你看对了.您提到的答案指向W3C编辑的2017年州草案,该草案已在过去两年中发展.目前的实施严格地说:
该标志被设置为当所述用户代理正在远程控制,其最初被设置为.
webdriver-active
true
false
进一步,
Navigator includes NavigatorAutomationInformation;
Run Code Online (Sandbox Code Playgroud)
需要注意的是:
不应在WorkerNavigator上公开该接口.
NavigatorAutomationInformation
的接口被定义为:NavigatorAutomationInformation
interface mixin NavigatorAutomationInformation {
readonly attribute boolean webdriver;
};
Run Code Online (Sandbox Code Playgroud)
如果设置了flag,则返回true,否则返回false.webdriver-active
最后,navigator.webdriver
定义了一种协作用户代理的标准方法,以通知文档它由WebDriver控制,以便在自动化期间触发备用代码路径.
更改任何这些参数可能会阻止导航并检测到WebDriver实例.
终于解决了ChromeDriver的问题,Chrome大于v79。
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-blink-features");
options.addArguments("--disable-blink-features=AutomationControlled");
ChromeDriver driver = new ChromeDriver(options);
Map<String, Object> params = new HashMap<String, Object>();
params.put("source", "Object.defineProperty(navigator, 'webdriver', { get: () => undefined })");
driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument", params);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5531 次 |
最近记录: |