Как сделать скрипт Selenium необнаружимым с помощью GeckoDriver и Firefox через Python?
Есть ли способ сделать ваш селен-скрипт необнаружимым в Python с помощью geckodriver
Я использую селен для соскоба. Есть ли какие-то средства защиты, которые нам нужно использовать, чтобы веб-сайты не могли обнаружить селен?
5 ответов
Тот факт, что обнаруживается управляемый селеном Firefox / GeckoDriver, не зависит от какой-либо конкретной версии GeckoDriver или Firefox. Сами веб-сайты могут обнаруживать сетевой трафик и могут идентифицировать клиента браузера, то есть веб-браузер, как управляемый WebDriver.
Согласно документации WebDriver Interface
в проекте самых последних редакторов в WebDriver - W3C Живого документ оwebdriver-active
flag, который изначально установлен как false, устанавливается в true, когда пользовательский агент находится под удаленным управлением, то есть при управлении через Selenium.
Теперь, когда 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.
Итак, суть в следующем:
Селен идентифицирует себя
Однако некоторые общие подходы, позволяющие избежать обнаружения при сканировании веб-страниц, заключаются в следующем:
- Первый и главный атрибут, который веб-сайт может определить для вашего скрипта / программы, - это размер вашего монитора. Поэтому рекомендуется не использовать обычное окно просмотра.
- Если вам нужно отправить несколько запросов на веб-сайт, вам нужно продолжать менять User Agent для каждого запроса. Здесь вы можете найти подробное обсуждение Как изменить пользовательский агент Google Chrome в Selenium?
- Чтобы имитировать человеческое поведение, вам может потребоваться замедлить выполнение скрипта, даже если WebDriverWait и ожидаемые_условия вызывают
time.sleep(secs)
. Здесь вы можете найти подробное обсуждение того, как засыпать webdriver в python на миллисекунды.
Существуют разные способы избежать обнаружения веб-сайтами использования Selenium.
При использовании Selenium значение navigator.webdriver по умолчанию установлено в значение true. Эта переменная будет присутствовать как в Chrome, так и в Firefox. Для этой переменной следует установить значение "undefined", чтобы избежать обнаружения.
Чтобы избежать обнаружения, также можно использовать прокси-сервер.
Некоторые веб-сайты могут использовать состояние вашего браузера, чтобы определить, используете ли вы 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)
Как только код будет запущен, вы сможете вручную проверить, что в браузере, запущенном Selenium, теперь есть история и расширения Firefox. Вы также можете ввести "navigator.webdriver" в консоль devtools, чтобы убедиться, что он не определен.
Согласно текущей :
Флаг webdriver-active устанавливается в значение true, когда пользовательский агент находится под удаленным управлением. Оно изначально ложно.
Следовательно, логический атрибут webdriver , доступный только для чтения, возвращает true, если установлен флаг активности webdriver, и false в противном случае.
Далее в спецификации уточняется:
navigator.webdriver Определяет стандартный способ взаимодействия пользовательских агентов для информирования документа о том, что он управляется WebDriver, например, чтобы во время автоматизации можно было активировать альтернативные пути кода.
Были тонны и миллионы дискуссий с требованием Feature: возможность отключить navigator.webdriver == true ?а также
@whimboo
в своем комментарии пришел к выводу, что:
это связано с тем, что спецификация WebDriver определяет это свойство в объекте Navigator, для которого должно быть установлено значение true, когда тесты выполняются с включенным веб-драйвером:
спецификации проекта WebDriver W3C Editorhttps://w3c.github.io/webdriver/#interface
Реализации должны соответствовать этому требованию. Таким образом, мы не предоставим способ обойти это.
Общий вывод
Из приведенных выше рассуждений можно сделать вывод, что:
Селен идентифицирует себя
и невозможно скрыть тот факт, что браузер управляется WebDriver.
Рекомендации
Однако некоторые пользователи предложили подходы, которые могут скрыть тот факт, что браузер Mozilla Firefox управляется WebDriver посредством использования профилей и прокси Firefox следующим образом:
код , совместимый с
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()
Другие альтернативы
Замечено , что в некоторых конкретных вариантах ОС пара различных настроек/конфигураций может обойти обнаружение ботов , а именно:
блок кода, совместимый с
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 следующим образом:
код PythonPython , совместимый с selenium4selenium4selenium4
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/")
Как указано в ответе выше , возвращениеtrue
при использовании соответствует спецификации.chromedriver
имеет возможность--disable-blink-features=AutomationControlled
отключить его, но Mozilla отказалась добавить эквивалент . До Firefox 88 можно было отключить черезdom.webdriver.enabled
, но это больше не поддерживается.useAutomationExtension
опубликовано в другом месте этой темы, но, похоже, это также относится к Chrome.
Вы можете переопределить значениеnavigator.webdriver
изменяя ответы с помощью selenium-wire
, как указано в этом ответе . Например, внедрив следующий скрипт:
Object.defineProperty(navigator, "webdriver", { get: () => false });
Однако этого недостаточно для имитации функциональностиundetected-chromedriver
, у которого на данный момент нет версии Firefox.
Это может показаться простым, но если вы посмотрите, как веб-сайт обнаруживает селен (или ботов), отслеживая движения, поэтому, если вы можете сделать свою программу немного похожей на то, как человек просматривает веб-сайт, вы можете получить меньше капчи, например добавить курсор /page движения прокрутки между вашими операциями и другие действия, которые имитируют просмотр. Таким образом, между двумя операциями попробуйте добавить некоторые другие действия, добавить некоторую задержку и т. д. Это сделает вашего бота медленнее и может остаться незамеченным.
Спасибо