/ парсеры

Пишем бота регистрации аккаунта на PHP, эмулируя AJAX-запросы на CURL

Пока вышла горячая статейка с основными приёмами при работе с cURL в PHP, я решил написать скрипт простого бота, работающего с AJAX, чтобы закрепить материал на реальном примере. В этой статье будут упускаться многие очевидные вещи, эта статья будет более ориентирована на демонстрацию подхода при написании ботов для любого сайта. Я, для текущего примера решил выбрать сайт webparse.ru, для которого мы напишем скрипт заполнения почты и регистрации нового аккаунта.

Забегу наперёд, и скажу, что для написания бота для этого сайта, необходимо будет эмулировать AJAX запросы из PHP, и обрабатывать JSON ответ от сервера.

Перед тем, как приступить к изучению этой статьи, советую сначала разобраться с основами PHP cURL, и основыми функциями по работе с ним. После чего, продолжите изучение этой.

Шаг 1 - изучаем жертву

Шаг, с которого всё всегда начинается - нужно открыть целевой сайт по ссылке, и изучить его: какие запросы ему нужно отправить, какие данные, заголовки, наличие капчи или подобной защиты.

Потому, для начала, переходим по ссылке webparse.ru, и сразу видим форму с вводом email адреса для регистрации: target_first_visit

Для того, чтобы понять, какие параметры нужно отправлять, и на какой URL-адрес, нужно:

  • включить отладочную панель в браузере (f12)
  • открыть вкладку Network (она же Сеть)
  • включить опцию Preserve log (если не включить её, то вся история запросов будет очищена при перезагрузку страницы, оно вам надо?).
    2s_step_site

После чего, нам нужно провести цикл действий, которые мы собираемся автоматизировать (наблюдая при этом за каждым выполненным запросом и переданными данными). Наш цикл действий состоит только из заполнения почты и клика по кнопке Зарегистрироваться.

И после клика по кнопке регистрации, будет отправлен AJAX-запрос, который мы увидим в открытой панеле. И уже из информации на этой панеле, мы можем изучить все данные, которые нам необходимо будет сэмулировать PHP-скриптом.

В нашем случае, на панеле добавится запрос на ajax_light_register, по которому мы должны кликнуть, для просмотра дополнительной информации. А именно, нас интересует URL-адрес, на который отправляются данные для регистрации, метод, данные, и их формат: defailts_request

Исходя их этой информации, мы понимаем, что нам нужно отправить данные методом POST на URL https://webparse.ru/module_auth/ajax_light_register, передав параметр email как почту для регистрации.

Однако, здесь есть один тонкий момент. Для того, чтобы полностью сэмулировать работу браузера, реального пользователя, нужно передать так же заголовки, которые помогут нам не выдать себя за бота.headers_explai_---n
Я выделил основные заголовки, которые в большей мере котируются сервером, которые желательно отправлять. Сейчас, кратко рассмотрим их назначение:

  • Accept - заголовок, указывающий на то, в каком формате вы хотите получить данные (JSON, HTML, XML и т.д.). Этот параметр необязательный, и, очень часто, игнорируемый сервером. Но, иногда бывает API, которое умеет отдавать данные в разных форматах, и ориентируется на значение этого заголовка.
  • Content-Type - заголовок, указывающий на то, в каком формате мы отправляем данные. В данном случае, указано application/x-www-form-urlencoded, что тоже является необязательным, потому как, по-умолчанию, он и подразумевается. Другой случай - когда передаётся JSON, тогда, Content-type указывается application/json.
  • Referer - URL-адрес, с которого мы отправляем запрос. Тоже необязательный параметр, однако, некоторые бот-детекторы проверяют этот параметр, ожидая, что он будет ссылаться на домен основного сайта (в текущем случае - webparse.ru).
  • X-Requested-With - обязательный параметр в текущем случае, со значением XMLHttpRequest, которое идентифицирует запрос как AJAX. Тоже, одна из примитивных проверок бот-детектора.
  • User-Agent - строка, указывающая на браузер, версию, ОС, и прочую мета-информацию о клиенте, выполняющего запрос. Его желательно передавать всегда, так как обычный браузер всегда передаёт эту информацию. И, если вы его не передаёте, то с вами явно что-то нечисто, и вас будет легко вычислить как бота.

Теперь, когда мы изучили основные параметры для написания собственного бота, объединим всю полученную информацию, и напишем скрипт на PHP.

Шаг 2 - изучаем ответ, полученный от сервера

Для того, чтобы сходу не спаммить лишний раз запросами к серверу, у нас есть возможность изучить пример ответа, когда мы пройдём регистрацию из браузера. Для этого, в открытой панеле информации о запросе нужно перейти на вкладку Preview, которая отображает ответ, полученный от сервера.

И вот, что мы имеем при успешном запросе: preview

Посмотрев на него, можно увидеть, что данные приходят в формате JSON, и содержат поля: errors (с массивом ошибок, если они есть), и errors_exists - булев флаг, показывающий, были ли ошибки при выполнении скрипта.
И, теперь, можем приступить к последнему шагу - написанию скрипта на PHP.

Шаг 3 - пишем скрипт и тестируем

Получив всю нужную информацию, напишем скрипт, который будет отправлять данные, полученные в шаге 1, и обрабатывая ответ, исходя из изученного примера во втором шаге.

$url = 'https://webparse.ru/module_auth/ajax_light_register';

$data = ['email' => 'test12321@spaces.ru'];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Accept: application/json, text/javascript, */*; q=0.01',
    'Referer: https://webparse.ru/',
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
    'X-Requested-With: XMLHttpRequest'
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

$data = json_decode(curl_exec($ch));

if($data->errors_exists) {
    echo 'Error request...';
    print_r($data->errors);
    die;
}

echo 'Успешный ответ. Письмо было отправлено на вашу почту.';
print_r($data); // [errors] => Array ( ) [errors_exists] => false

В результате чего, выполнив написанный скрипт, регистрация будет выполнена успешно, и на указанную почту будет отправлена ссылка для входа в личный кабинет.

Резюме

В этой статья я продемонстрировал подход, которому следую при написании ботов на PHP. В этой статье были затронуты темы написания ботов, эмулирующих AJAX-запросы на PHP, темы возможных защит и бот-детекторов, которые мы научились обходить. Итого, из
этой статьи на узнали, как написать бота на PHP, как в PHP определяют ботов, как в PHP cURL задать User-Agent, и зачем он нужен, и как при написании собственного бота не попасться на эти детекторы. Дальше - больше: продвинутые темы парсинга, полезные инструменты, написания ботов на PHP, многопоточная работа.

Основная идея реализации ботов должна была появиться в вашей голове сама собой: имитация браузера в PHP (при написании ботов) происходит на основе изучения сайта-донора и воссоздание последовательности HTTP-запросов, как на сайте-доноре. То есть, при написании ботов вам не нужно программировать браузер, типа: нажать на кнопку с название "регистрация", ввести почту в форму, подтвердить, запустить JavaScript... Вам нужно всего лишь понять, куда, какие, и какого типа данные нужно отправлять, и воссоздать отправку этих данных в скрипте curl-запросами (или другими аналогами). И ваша последовательность теперь будет выглядеть как: отправить на URL http://... методом POST данные [...], прочитать ответ, обработать, повторить, или продолжить дальше и т.д.