是否存在无法检测到的 Selenium WebDriver 版本?

Posted

技术标签:

【中文标题】是否存在无法检测到的 Selenium WebDriver 版本?【英文标题】:Is there a version of Selenium WebDriver that is not detectable? 【发布时间】:2019-10-24 23:40:26 【问题描述】:

我在住宅代理网络后面的Ubuntu 服务器上通过 Selenium 运行 Chrome 驱动程序。然而,我的 Selenium 正在被检测到。有没有办法让 Chrome 驱动程序和 Selenium 100% 不可检测?

我已经尝试了很长时间,以至于忘记了我做过的许多事情,包括:

    尝试不同版本的 Chrome 从 Chrome 驱动程序文件中添加几个标志并删除一些单词。 使用隐身模式在代理(也包括住宅代理)后面运行它。 正在加载配置文件。 鼠标随机移动。 随机化一切。

我正在寻找 100% 无法检测到的真实版本的 Selenium。如果那曾经存在过。或者机器人跟踪器无法检测到的另一种自动化方式。

这是浏览器启动的一部分:

sx = random.randint(1000, 1500)
sn = random.randint(3000, 4500)

display = Display(visible=0, size=(sx,sn))
display.start()


randagent = random.randint(0,len(useragents_desktop)-1)

uag = useragents_desktop[randagent]
#this is to prevent ip leaking
preferences =
    "webrtc.ip_handling_policy" : "disable_non_proxied_udp",
    "webrtc.multiple_routes_enabled": False,
    "webrtc.nonproxied_udp_enabled" : False

chrome_options.add_experimental_option("prefs", preferences)
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-impl-side-painting")
chrome_options.add_argument("--disable-setuid-sandbox")
chrome_options.add_argument("--disable-seccomp-filter-sandbox")
chrome_options.add_argument("--disable-breakpad")
chrome_options.add_argument("--disable-client-side-phishing-detection")
chrome_options.add_argument("--disable-cast")
chrome_options.add_argument("--disable-cast-streaming-hw-encoding")
chrome_options.add_argument("--disable-cloud-import")
chrome_options.add_argument("--disable-popup-blocking")
chrome_options.add_argument("--ignore-certificate-errors")
chrome_options.add_argument("--disable-session-crashed-bubble")
chrome_options.add_argument("--disable-ipv6")
chrome_options.add_argument("--allow-http-screen-capture")
chrome_options.add_argument("--start-maximized")

wsize = "--window-size=" +  str(sx-10) + ',' + str(sn-10)
chrome_options.add_argument(str(wsize) )

prefs = "profile.managed_default_content_settings.images": 2
chrome_options.add_experimental_option("prefs", prefs)

chrome_options.add_argument("blink-settings=imagesEnabled=true")
chrome_options.add_argument("start-maximized")
chrome_options.add_argument("user-agent="+uag)
chrome_options.add_extension(pluginfile)#this is for the residential proxy
driver = webdriver.Chrome(executable_path="/usr/bin/chromedriver", chrome_options=chrome_options)

【问题讨论】:

您查看过this question 以了解更多信息吗?每个网站如何以及是否进行机器人检测都会有所不同。他们可能通过 javascript 工作,或者他们可能正在检查服务器上的内容,例如,一些自动化工具还设置了适当的用户代理字符串。 我完成了 99% 的工作,还有很多事情没有任何效果.. 您是否尝试覆盖 userAgent?你在用无头浏览器吗? 简单的答案。不,这是不可能的 Can a website detect when you are using selenium with chromedriver?的可能重复 【参考方案1】:

为什么不试试undetected-chromedriver?

优化的 Selenium Chromedriver 补丁,不会触发 Distill Network / Imperva / DataDome / Botprotect.io 等反僵尸服务自动下载驱动程序二进制文件并对其进行修补。

测试到当前的 chrome beta 版本 也适用于 Brave Browser 和许多其他基于 Chromium 的浏览器 Python 3.6++

你可以安装它:pip install undetected-chromedriver

您应该注意以下重要事项: 由于模块的内部工作原理,需要以编程方式浏览(即:使用 .get(url) )。切勿使用 gui 导航。使用键盘和鼠标进行导航可能会导致检测!新标签:同样的故事。如果你真的需要多标签,那么打开带有空白页面的标签(提示:url 是数据:,包括逗号,是的,驱动程序接受它)并照常做你的事情。如果您遵循这些“规则”(实际上是它的默认行为),那么您现在会玩得很开心。

In [1]: import undetected_chromedriver as uc
In [2]: driver = uc.Chrome()
In [3]: driver.execute_script('return navigator.webdriver')
Out[3]: True  # Detectable
In [4]: driver.get('https://distilnetworks.com') # starts magic
In [4]: driver.execute_script('return navigator.webdriver')
In [5]: None  # Undetectable!

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review 这里的多标签问题日志:github.com/ultrafunkamsterdam/undetected-chromedriver/issues/27 我一直在手动修改 chromedriver 使其无法检测到,但随后 citi.com 停止允许我登录。这可以让我再次登录 Citi。而且比自己做更容易。【参考方案2】:

selenium 驱动的 WebDriver 被检测到 这一事实取决于任何特定的 SeleniumChromeChromeDriver 版本。 网站本身可以检测网络流量,并可以将浏览器客户端,即Web浏览器识别为WebDriver控制

然而,一些避免在网络抓取时被检测到的通用方法如下:

网站可以确定您的脚本/程序的首要属性是通过您的显示器大小。所以建议不要使用常规的Viewport。 如果您需要向一个网站发送多个请求,您需要不断更改每个请求的user-agent。你可以在Way to change Google Chrome user agent in Selenium?找到详细的讨论 要模拟 类人 行为,您可能需要减慢脚本执行速度,甚至超过 WebDriverWait 和 expected_conditions 诱导 time.sleep(secs)。在这里你可以找到关于How to sleep webdriver in python for milliseconds的详细讨论

@Antoine Vastel 在他的博客网站Detecting Chrome Headless 中提到了几种方法,它们将 Chrome 浏览器与 headless Chrome 浏览器区分开来。

用户代理:用户代理属性通常用于检测操作系统以及用户的浏览器。对于 Chrome 版本 59,它具有以下值:

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) HeadlessChrome/59.0.3071.115 Safari/537.36

可以通过以下方式检查是否存在 Chrome headless

if (/HeadlessChrome/.test(window.navigator.userAgent)) 
    console.log("Chrome headless detected");

插件navigator.plugins 返回浏览器中存在的插件数组。通常,在 Chrome 上,我们会找到默认插件,例如 Chrome PDF viewerGoogle Native Client。相反,在无头模式下,返回的数组包含 no 插件。

可以通过以下方式检查是否存在 插件

if(navigator.plugins.length == 0) 
    console.log("It may be Chrome headless");

语言:在 Chrome 中,两个 Javascript 属性可以获取 user: navigator.languagenavigator.languages 使用的语言。第一个是浏览器 UI 的语言,而第二个是代表用户首选语言的字符串数组。但是,在无头模式下,navigator.languages 返回一个 empty 字符串。

可以通过以下方式检查是否存在语言

if(navigator.languages == "") 
     console.log("Chrome headless detected");

WebGL:WebGL 是一种在 HTML 画布中执行 3D 渲染的 API。使用此 API,可以查询图形驱动程序的供应商以及图形驱动程序的渲染器。使用普通的 Chrome 和 Linux,我们可以获得以下渲染器和供应商的值:Google SwiftShaderGoogle Inc.。在无头模式下,我们可以获得Mesa OffScreen,这是一种不使用任何窗口系统的渲染技术和Brian Paul,这是启动开源Mesa图形库的程序。

可以通过以下方式检查是否存在 WebGL

var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl');

var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);

if(vendor == "Brian Paul" && renderer == "Mesa OffScreen") 
    console.log("Chrome headless detected");

并非所有 Chrome 无头浏览器都具有相同的供应商和渲染器值。其他人保留在非无头版本上也可以找到的值。但是,Mesa OffscreenBrian Paul 表示存在无头版本。

浏览器功能:Modernizr 库可以测试浏览器中是否存在各种 HTML 和 CSS 功能。我们发现 Chrome 和无头 Chrome 之间的唯一区别是后者没有细线功能,该功能检测到对 hidpi/retina hairlines 的支持。

可以通过以下方式检查是否存在细线特征

if(!Modernizr["hairline"]) 
    console.log("It may be Chrome headless");

缺少图像:我们列表中的最后一个似乎也是最可靠的,它来自 Chrome 使用的图像尺寸,以防图像无法加载。在普通 Chrome 的情况下,图像的宽度和高度取决于浏览器的缩放,但不为零。在无头 Chrome 中,图像的宽度和高度均为零。

可以通过以下方式检查是否存在缺失图像

var body = document.getElementsByTagName("body")[0];
var image = document.createElement("img");
image.src = "http://iloveponeydotcom32188.jg";
image.setAttribute("id", "fakeimage");
body.appendChild(image);
image.onerror = function()
    if(image.width == 0 && image.height == 0) 
    console.log("Chrome headless detected");
    
   

参考

您可以在以下位置找到几个类似的讨论:

How to bypass Google captcha with Selenium and python? How to make Selenium script undetectable using GeckoDriver and Firefox through Python?

tl;博士

Selenium webdriver: Modifying navigator.webdriver flag to prevent selenium detection How does recaptcha 3 know I'm using selenium/chromedriver? Selenium and non-headless browser keeps asking for Captcha

【讨论】:

嗨,感谢您提供的信息,我已经完成了大部分此类工作以及更多工作。我仍然被检测到。是否有一个脚本的链接,它实现了所有这些东西,我可以用作指南? selenium 标识自己:w3c.github.io/webdriver/…

以上是关于是否存在无法检测到的 Selenium WebDriver 版本?的主要内容,如果未能解决你的问题,请参考以下文章

Selenium 高阶应用之WebDriverWait 和 expected_conditions

selenium模块

如何通过 Python 使用 GeckoDriver 和 Firefox 使 Selenium 脚本无法检测?

Python教程:selenium模块用法教程

未检测到的 Chromedriver 未正确加载

检测在 selenium java 中下载的文件