如何通过 Python 使用 GeckoDriver 和 Firefox 使 Selenium 脚本无法检测?
How can I make a Selenium script undetectable using GeckoDriver and Firefox through Python?
有没有办法使用 geckodriver 让您的 Selenium 脚本在 Python 中检测不到?
我正在使用 Selenium 进行抓取。我们是否需要使用任何保护措施才能使网站无法检测到 Selenium?
事实上 selenium 驱动 Firefox / GeckoDriver 被检测到 并不依赖于任何特定的 GeckoDriver 或 Firefox 版本。 Websites 本身可以检测网络流量并可以识别 Browser Client 即 Web Browser 作为 WebDriver 控制.
根据 WebDriver Interface
in the latest editor's draft of WebDriver - W3C Living Document the webdriver-active
flag which is initially set as false, is set to true when the user agent is under remote control i.e. when controlled through 的文档。
现在 NavigatorAutomationInformation
接口不应暴露在 WorkerNavigator
.
所以,
webdriver
Returns true if webdriver-active flag is set, false otherwise.
其中,
navigator.webdriver
Defines a standard way for co-operating user agents to inform the document that it is controlled by WebDriver, for example so that alternate code paths can be triggered during automation.
所以,底线是:
Selenium identifies itself
然而,一些避免在网络抓取时被检测到的通用方法如下:
- 网站可以确定您的 script/program 的首要属性是通过您的 显示器大小 。所以建议不要使用常规的Viewport.
- 如果您需要向一个网站发送多个请求,则需要在每个请求中不断更改 User Agent。在这里您可以找到关于
的详细讨论
- 为了模拟人类行为,您可能需要减慢脚本执行速度甚至超过WebDriverWait and expected_conditions inducing
time.sleep(secs)
. Here you can find a detailed discussion on
有多种方法可以避免网站检测到 Selenium 的使用。
navigator.webdriver的值在使用Selenium时默认设置为true。此变量将出现在 Chrome 以及 Firefox 中。此变量应设置为“未定义”以避免检测。
也可以使用代理服务器来避免检测。
一些网站能够使用浏览器的状态来确定您是否在使用 Selenium。您可以将 Selenium 设置为使用自定义浏览器配置文件来避免这种情况。
下面的代码使用了所有这三种方法。
profile = webdriver.FirefoxProfile('C:\Users\You\AppData\Roaming\Mozilla\Firefox\Profiles\something.default-release')
PROXY_HOST = "12.12.12.123"
PROXY_PORT = "1234"
profile.set_preference("network.proxy.type", 1)
profile.set_preference("network.proxy.http", PROXY_HOST)
profile.set_preference("network.proxy.http_port", int(PROXY_PORT))
profile.set_preference("dom.webdriver.enabled", False)
profile.set_preference('useAutomationExtension', False)
profile.update_preferences()
desired = DesiredCapabilities.FIREFOX
driver = webdriver.Firefox(firefox_profile=profile, desired_capabilities=desired)
代码为 运行 后,您将能够手动检查浏览器 运行 by Selenium 现在是否具有您的 Firefox 历史记录和扩展。您还可以在开发工具控制台中输入“navigator.webdriver”来检查它是否未定义。
根据当前 WebDriver W3C Editor's Draft 规范:
The webdriver-active flag is set to true when the user agent is under remote control. It is initially false.
因此,readonly boolean 属性 webdriver returns 如果设置了 webdriver-active 标志,则为 true,否则为 false .
进一步规范进一步阐明:
navigator.webdriver Defines a standard way for co-operating user
agents to inform the document that it is controlled by WebDriver, for
example so that alternate code paths can be triggered during
automation.
有无数次讨论要求 Feature: option to disable navigator.webdriver == true ? and @whimboo
in his comment 得出以下结论:
that is because the WebDriver spec defines that property on the
Navigator object, which has to be set to true when tests are running
with webdriver enabled:
https://w3c.github.io/webdriver/#interface
Implementations have to be conformant to this requirement. As such we
will not provide a way to circumvent that.
一般性结论
从以上讨论可以得出结论:
Selenium identifies itself
并且无法隐藏浏览器受 驱动的事实。
建议
然而,一些用户建议的方法可以通过使用 and 来隐藏 Mozilla Firefox 浏览器是 WebDriver 控制的事实,如下所示:
from selenium.webdriver import Firefox
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
profile_path = r'C:\Users\Admin\AppData\Roaming\Mozilla\Firefox\Profiles\s8543x41.default-release'
options=Options()
options.set_preference('profile', profile_path)
options.set_preference('network.proxy.type', 1)
options.set_preference('network.proxy.socks', '127.0.0.1')
options.set_preference('network.proxy.socks_port', 9050)
options.set_preference('network.proxy.socks_remote_dns', False)
service = Service('C:\BrowserDrivers\geckodriver.exe')
driver = Firefox(service=service, options=options)
driver.get("https://www.google.com")
driver.quit()
其他选择
观察到在一些具体的os variants a couple of diverse settings/configuration can bypass the bot检测中,如下:
selenium4 compatible code block
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.chrome.service import Service
options = Options()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('excludeSwitches', ['enable-logging'])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument('--disable-blink-features=AutomationControlled')
s = Service('C:\BrowserDrivers\geckodriver.exe')
driver = webdriver.Chrome(service=s, options=options)
可能的解决方案
一个可能的解决方案是使用 tor 浏览器,如下所示:
from selenium.webdriver import Firefox
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
import os
torexe = os.popen(r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Tor\tor.exe')
profile_path = r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Data\Browser\profile.default'
firefox_options=Options()
firefox_options.set_preference('profile', profile_path)
firefox_options.set_preference('network.proxy.type', 1)
firefox_options.set_preference('network.proxy.socks', '127.0.0.1')
firefox_options.set_preference('network.proxy.socks_port', 9050)
firefox_options.set_preference("network.proxy.socks_remote_dns", False)
firefox_options.binary_location = r'C:\Users\username\Desktop\Tor Browser\Browser\firefox.exe'
service = Service('C:\BrowserDrivers\geckodriver.exe')
driver = webdriver.Firefox(service=service, options=firefox_options)
driver.get("https://www.tiktok.com/")
这听起来可能很简单,但是如果你看看网站是如何通过跟踪动作来检测 selenium(或机器人)的,那么如果你可以让你的程序稍微像人类浏览网站一样,你可以获得更少的验证码,例如在操作之间添加 cursor/page 滚动动作 ,以及其他模仿浏览的动作。因此,在两个操作之间尝试添加一些其他操作,添加一些延迟等。这会使您的机器人变慢并且可能无法被发现。
谢谢
有没有办法使用 geckodriver 让您的 Selenium 脚本在 Python 中检测不到?
我正在使用 Selenium 进行抓取。我们是否需要使用任何保护措施才能使网站无法检测到 Selenium?
事实上 selenium 驱动 Firefox / GeckoDriver 被检测到 并不依赖于任何特定的 GeckoDriver 或 Firefox 版本。 Websites 本身可以检测网络流量并可以识别 Browser Client 即 Web Browser 作为 WebDriver 控制.
根据 WebDriver Interface
in the latest editor's draft of WebDriver - W3C Living Document the webdriver-active
flag which is initially set as false, is set to true when the user agent is under remote control i.e. when controlled through
现在 NavigatorAutomationInformation
接口不应暴露在 WorkerNavigator
.
所以,
webdriver
Returns true if webdriver-active flag is set, false otherwise.
其中,
navigator.webdriver
Defines a standard way for co-operating user agents to inform the document that it is controlled by WebDriver, for example so that alternate code paths can be triggered during automation.
所以,底线是:
Selenium identifies itself
然而,一些避免在网络抓取时被检测到的通用方法如下:
- 网站可以确定您的 script/program 的首要属性是通过您的 显示器大小 。所以建议不要使用常规的Viewport.
- 如果您需要向一个网站发送多个请求,则需要在每个请求中不断更改 User Agent。在这里您可以找到关于
- 为了模拟人类行为,您可能需要减慢脚本执行速度甚至超过WebDriverWait and expected_conditions inducing
time.sleep(secs)
. Here you can find a detailed discussion on
有多种方法可以避免网站检测到 Selenium 的使用。
navigator.webdriver的值在使用Selenium时默认设置为true。此变量将出现在 Chrome 以及 Firefox 中。此变量应设置为“未定义”以避免检测。
也可以使用代理服务器来避免检测。
一些网站能够使用浏览器的状态来确定您是否在使用 Selenium。您可以将 Selenium 设置为使用自定义浏览器配置文件来避免这种情况。
下面的代码使用了所有这三种方法。
profile = webdriver.FirefoxProfile('C:\Users\You\AppData\Roaming\Mozilla\Firefox\Profiles\something.default-release')
PROXY_HOST = "12.12.12.123"
PROXY_PORT = "1234"
profile.set_preference("network.proxy.type", 1)
profile.set_preference("network.proxy.http", PROXY_HOST)
profile.set_preference("network.proxy.http_port", int(PROXY_PORT))
profile.set_preference("dom.webdriver.enabled", False)
profile.set_preference('useAutomationExtension', False)
profile.update_preferences()
desired = DesiredCapabilities.FIREFOX
driver = webdriver.Firefox(firefox_profile=profile, desired_capabilities=desired)
代码为 运行 后,您将能够手动检查浏览器 运行 by Selenium 现在是否具有您的 Firefox 历史记录和扩展。您还可以在开发工具控制台中输入“navigator.webdriver”来检查它是否未定义。
根据当前 WebDriver W3C Editor's Draft 规范:
The webdriver-active flag is set to true when the user agent is under remote control. It is initially false.
因此,readonly boolean 属性 webdriver returns 如果设置了 webdriver-active 标志,则为 true,否则为 false .
进一步规范进一步阐明:
navigator.webdriver Defines a standard way for co-operating user agents to inform the document that it is controlled by WebDriver, for example so that alternate code paths can be triggered during automation.
有无数次讨论要求 Feature: option to disable navigator.webdriver == true ? and @whimboo
in his comment 得出以下结论:
that is because the WebDriver spec defines that property on the Navigator object, which has to be set to true when tests are running with webdriver enabled:
https://w3c.github.io/webdriver/#interface
Implementations have to be conformant to this requirement. As such we will not provide a way to circumvent that.
一般性结论
从以上讨论可以得出结论:
Selenium identifies itself
并且无法隐藏浏览器受
建议
然而,一些用户建议的方法可以通过使用
from selenium.webdriver import Firefox
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
profile_path = r'C:\Users\Admin\AppData\Roaming\Mozilla\Firefox\Profiles\s8543x41.default-release'
options=Options()
options.set_preference('profile', profile_path)
options.set_preference('network.proxy.type', 1)
options.set_preference('network.proxy.socks', '127.0.0.1')
options.set_preference('network.proxy.socks_port', 9050)
options.set_preference('network.proxy.socks_remote_dns', False)
service = Service('C:\BrowserDrivers\geckodriver.exe')
driver = Firefox(service=service, options=options)
driver.get("https://www.google.com")
driver.quit()
其他选择
观察到在一些具体的os variants a couple of diverse settings/configuration can bypass the bot检测中,如下:
selenium4 compatible code block
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.chrome.service import Service
options = Options()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('excludeSwitches', ['enable-logging'])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument('--disable-blink-features=AutomationControlled')
s = Service('C:\BrowserDrivers\geckodriver.exe')
driver = webdriver.Chrome(service=s, options=options)
可能的解决方案
一个可能的解决方案是使用 tor 浏览器,如下所示:
from selenium.webdriver import Firefox
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
import os
torexe = os.popen(r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Tor\tor.exe')
profile_path = r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Data\Browser\profile.default'
firefox_options=Options()
firefox_options.set_preference('profile', profile_path)
firefox_options.set_preference('network.proxy.type', 1)
firefox_options.set_preference('network.proxy.socks', '127.0.0.1')
firefox_options.set_preference('network.proxy.socks_port', 9050)
firefox_options.set_preference("network.proxy.socks_remote_dns", False)
firefox_options.binary_location = r'C:\Users\username\Desktop\Tor Browser\Browser\firefox.exe'
service = Service('C:\BrowserDrivers\geckodriver.exe')
driver = webdriver.Firefox(service=service, options=firefox_options)
driver.get("https://www.tiktok.com/")
这听起来可能很简单,但是如果你看看网站是如何通过跟踪动作来检测 selenium(或机器人)的,那么如果你可以让你的程序稍微像人类浏览网站一样,你可以获得更少的验证码,例如在操作之间添加 cursor/page 滚动动作 ,以及其他模仿浏览的动作。因此,在两个操作之间尝试添加一些其他操作,添加一些延迟等。这会使您的机器人变慢并且可能无法被发现。
谢谢