Задать вопрос
kshnkvn
@kshnkvn
yay ✌️ t.me/kshnkvn

Какие могут быть способы определения автоматизации Selenium?

Допустим есть сайт example.com на котором я пытаюсь автоматизировать процесс регистрации. Процент успеха крайне низкий. Что я пробовал:
1. Прокси. Паблик-листы, приват-листы, luminati, microleaves - все практически безуспешно. Остановился на варианте поднятия микросерверов google cloud и запуска через них прокси - изредка регистрация происходит.
2. User-agent и OS естественно рандомно меняются, только актуальные версии.
3. В самом скрипте очень много рандома - на каждую форму ввода происходит наводка мышки, клик по форме, ввод данных пользователя не сразу, а примерно так:
fn_form = WebDriverWait(driver, 10).until(ec.visibility_of_element_located((By.XPATH, '//input[@name="firstname"]')))
action = ActionChains(driver)
action.move_to_element(fn_form).perform(); time.sleep(random.uniform(0.1, 0.5))
fn_form.click()
for character in user_info['first_name']:
    fn_form.send_keys(character)
    time.sleep(random.uniform(0.1, 0.3))

Переключения между формами помимо наведения мышки и клика пробовал с помощью нажатия Tab:
driver.find_element(By.XPATH, '//body').send_keys(Keys.TAB); time.sleep(random.uniform(0.1, 0.5))

Листать страницу "туда-сюда" некуда, т.к. она ровно по размеру экрана.
4. Пробовал запускать Selenium через свой профиль браузера, на случай если есть проверка на fingerprint - сомнительная успешность.
5. Просматривал все запросы во вкладке Network - все параметры и передаваемые cookies 100% идентичны тем, которые передаются при успешной регистрации или вручную, или через сам Selenium, просто в какой-то момент при нажатии на кнопку "Регистрации" в Network появляются несколько запросов следующего содержания:
?cid=102
Request URL: https://example.com/reg/submit/?cid=102
Request Method: POST
Status Code: 302
Remote Address: 34.94.235.219:3128
Referrer Policy: origin-when-cross-origin

https://example.com/sem_pixel/1/control/0/

Request URL: https://example.com/sem_pixel/1/control/0/
Request Method: GET
Status Code: 302
Remote Address: 34.94.235.219:3128
Referrer Policy: origin-when-cross-origin
access-control-allow-credentials: true
access-control-allow-methods: OPTIONS
access-control-allow-origin: https://example.com
access-control-expose-headers: X-FB-Debug, X-Loader-Length
cache-control: private, no-cache, no-store, must-revalidate
content-length: 0
content-security-policy: frame-ancestors 'self';
content-security-policy: default-src * data: blob: 'self';script-src *.example.com *.excdn.net *.example.com *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.example.com example.com *.fbcdn.net *.example.com *.spotilocal.com:*'self';
content-type: text/html; charset=utf-8
date: Thu, 25 Jul 2019 14:22:27 GMT
expires: Sat, 01 Jan 2000 00:00:00 GMT
location: https://example.com/confirmemail.php?next=https%3A...
pragma: no-cache
status: 302
strict-transport-security: max-age=15552000; preload; includeSubDomains
vary: Origin
x-content-type-options: nosniff
x-fb-debug: McXnUwM163ur8MkdlphCspXutCohCp808mkbnGwCnsYlKYPyhYm9xYhQTNyE7aCwv+DrQvYCQJBp5G9oz2FrOw==
x-xss-protection: 0
:authority: example.com
:method: GET
:path: /sem_pixel/1/control/0/
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
accept-encoding: gzip, deflate, br
accept-language: en,en_US;q=0.9
cookie: datr=Drs5XX3GHZ5kfWz0XfWdTt3s; sb=Drs5XYusCGzt1jiFHJVyzodj; c_user=100040010132196; xs=47%3AitezblUuA4TlFw%3A2%3A1564064545%3A-1%3A-1; fr=5SJ6UZc1le4OQSjBD.AWWSJPijLCZbTY9q_4Bm_0NlvO8.BdObsh.jT.AAA.0.0.BdObsh.AWWqN68S
referer: https://example.com/login/save-device/?login_sourc...
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0

Первый запрос есть и при успешной регистрации 1 в 1, но у него статус 200, второй запрос появляется только при неуспешной регистрации.
Может кто подскажет какие есть еще варианты "притвориться пользователем"?
  • Вопрос задан
  • 4300 просмотров
Подписаться 9 Средний Комментировать
Решения вопроса 1
kshnkvn
@kshnkvn Автор вопроса
yay ✌️ t.me/kshnkvn
Перепробовал кучу разных вариантов, вот что из них может сработать для кого-то (не для меня):
1. Очень сомнительно, но некоторые люди пишут, что для них это работало:
Изменение название переменной документа js, используемой Selenium - $cdc_. Для этого достаточно открыть файл chromedriver.exe в любом шестнадцатеричном редакторе (я использовал HxD) изменить её название на любое другое. Это не сработало для меня, но сам chromedriver работает нормально после этого. Так-же я пробовал изменить все переменные где есть слова driver, но это была плохая идея - chromedriver перестал запускать. Без изменения исходников тут точно не обойтись, но я не уверен что это может сработать.
2. Это более действующий вариант, который даёт хоть какой-то результат. На этой странице можно определить используется chromedriver, или нет и при запуске этой страницы через selenium действительно отображается, что используется webdriver. Добавление следующего куска кода помогло обойти эту идентификацию:
options.add_experimental_option("excludeSwitches", ['enable-automation'])

Но это всё-равно не помогло мне.
Так-же нашел очень сомнительное и вероятнее всего просто нерабочее решение:
Запуск js-кода, который меняет состояние переменных navigator, включая navigator.webdriver.
Так он запускается:
driver.execute_script("var s=window.document.createElement('script'); s.src='javascript.js';window.document.head.appendChild(s);")

Сам js-код
// overwrite the 'languages' property to use a custom getter
const setProperty = () => {
    Object.defineProperty(navigator, "languages", {
        get: function() {
            return ["en-US", "en", "es"];
        }
    });

    // Overwrite the 'plugins' property to use a custom getter.
    Object.defineProperty(navigator, 'plugins', {
        get: () => [1, 2, 3, 4, 5],
    });

    // Pass the Webdriver test
    Object.defineProperty(navigator, 'webdriver', {
      get: () => false,
    });
    callback();
};
setProperty();

Ерунда в том, что в Chrome вообще отсутствует переменная navigator.webdriver, в этом можно убедиться вводом navigator в консоли браузера, её там нет. Зато эта переменная есть в Firefox, но этот код её не меняет, т.е. он просто ничего не делает, значение переменной Firefox navigator.webdriver всегда равно true при запуске через selenium. В обычном (ручном) режиме она false.

UPD. Не знаю, как проглядел, но в конечном итоге всё уперлось в проверку reCAPTCHA v3. Эта проверка проходится практически всегда при следующих условиях:
1. Не используется User-Agent.
2. Не используется прокси.
3. Не отключаются уведомления.
4. Не блокируются запросы на разрешения.
4. Используется вот этот параметр:
options.add_experimental_option("excludeSwitches", ['enable-automation'])

Но при таких параметрах зарегистрировать более одного раза с одного IP не представляется возможным. Как я и указывал в своём вопросе - прокси использовал совершенно разные - от паблик до микро-серверов google cloud, так что дело не в "качестве" прокси а сугубо в факте его использования.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@DanyaMo
C#/.Net developer
Ещё можно вместо Selenium использовать Puppeteer с подключенным плагином puppeteer-extra-plugin-stealth.

Как минимум этот тест проходит
Ответ написан
Комментировать
dimonchik2013
@dimonchik2013
non progredi est regredi
подпишусь

не подскажут - сейчас это коммерческая инфа

ну из того что можно рассказать - поменьше headless ))
но - все гораздо сложнее
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы