Пишем простой авторегистратор. Часть 3 - боремся с капчей.

Содержание

  1. Инструментарий
  2. Основы
  3. Боремся с капчей
  4. Подключаем антикапчу
  5. Подтверждение по email
  6. Пишем модуль для RegSubmitter

В предыдущей статье мы рассмотрели самый простой пример авторегистратора, которому надо всего лишь отправить форму. Но таких сервисов очень мало, поэтому гораздо чаще приходится во время регистрации видеть перед собой капчу. Сегодня "ляжет под нож" сервис Мое Место.

Шаг 1. Анализ защиты.

В первую очередь, следует убедиться, что капча вообще есть :) То, что есть картинка, еще не значит, что есть капча. Как это ни удивительно, но бывают сайты, на которых капча создает сложности только для людей, но не для роботов. Кстати, завтра будет ровно год статье, в которой я писал как раз про такие случаи. Советую прочесть ее, прежде чем читать дальше.

Если вы убедились, что капча действительно не обходится простыми методами, то придется смириться и перейти к изучению защиты. Я встречал два метода проверки валидности капчи:

  1. Капча привязывалась к сессии и сессионный идентификатор передавался через cookies
  2. Сессионный ключ передается в скрытом поле формы.
  3. Комбинация первых двух

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

В особо тяжелых случаях таких полей бывает несколько, поэтому надо отследить их все.

Шаг 2. Пишем код.

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

Капчу мы будем вводить ручками, но это только до следующей статьи :)

При написании кода надо обратить внимание на две вещи:

  • HTML-код скрытого поля с сессионным ключом. Основываясь на нем надо будет составлять регулярное выражение.
  • Адрес картинки. При использовании сессионного ключа часто добавляют его к адресу картинки. На это тоже следует обратить внимание.

header('Content-Type: text/html; charset=UTF-8');
function register1()
{
 // Особая, curl-ная магия
 $ch = curl_init(); // Инициализируем сессию
 curl_setopt($ch, CURLOPT_URL,"http://moemesto.ru/register/"); // задаем адрес формы
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Результат нам нужно вернуть в переменную, а не на экран
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // Переходить по редиректам
 curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); // Указываем файл для хранения кукисов
 // Выполняем запрос
 $result = curl_exec($ch);
 // При помощи простейшего регулярного выражения добываем сессионный ключ
 preg_match('##i', $result, $key);
 curl_setopt($ch, CURLOPT_URL,"http://moemesto.ru/captcha/$key[1]"); // задаем адрес картинки
 $result = curl_exec($ch); // Скачиваем картинку
 curl_close ($ch); // Закрываем сессию
 file_put_contents('captcha.jpg', $result); // Сохраняем
 return $key[1]; // Возвращаем добытый ключ
}
// Функция, производящая регистрацию
function register2($login, $email, $password, $captcha, $key)
{
 // Все POST-параметры, которые надо отправить
 $post = array(
  'captchaid' => $key, // Передаем сессионный ключ
  'login'  => $login // Логин
  'email'  => $email, // Емейл
  'password' => $password, // Пароль
  'captcha' => $captcha, // А это наш код с картинки
  'do_reg' => 'Зарегистрироваться', // "Нажимаем" кнопку отправить ;-)
 );
 // Особая, curl-ная магия
 $ch = curl_init(); // Инициализируем сессию
 curl_setopt($ch, CURLOPT_URL,"http://moemesto.ru/register/"); // задаем адрес обработчика формы
 curl_setopt($ch, CURLOPT_POST, 1); // Указываем, что нам нужно отправить POST-запрос
 curl_setopt($ch, CURLOPT_POSTFIELDS, $post); // Передаем POST-параметры
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Результат нам нужно вернуть в переменную, а не на экран
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // Переходить по редиректам
 curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); // Указываем файл для хранения кукисов. При чем он должен быть тот же, что и в прошлый раз, чтобы кукисы подхватились.
 // Запускаем запрос!
 $result = curl_exec($ch);
 curl_close ($ch); // Закрываем сессию
 // Проверяем на успешность регистрации
 if(strstr($result, 'Поздравляем! Вы успешно зарегистрировались!'))
 {
  return true;
 }
 else
 {
  return false;
 }
}
// Параметры регистрации. Их можно задавать руками, или считывать из файла - на ваше усмотрение.
$login = 'antifrager223';
$email = '[email protected]';
$password = 'qwerty';
// Выводим, что мы будем регать
echo "Логин: $login, пароль: $password, email: $email
"
; // Если мы уже ввели капчу, то заканчиваем регистрацию if(!empty($_GET['captcha'])) { // Регаем if(register2($login, $email, $password, $_GET['captcha'], $_GET['key'])) { echo 'Успешно зарегистрирован'; else { echo 'Ошибка регистрации'; } echo '
basename
(__FILE__).'">Еще раз'; } else { // Если капчу еще не ввели - отображаем ее и просим ввести :) $key = register1(); $form = '

Введите код с картинки

$key.'"> '; echo $form; } // Все! ;-) ?>

Вот и все дела. Как и в прошлый раз, в коде есть пара синтаксических ошибок "от дурака", а в остальном он полностью рабочий, он же есть и во вложении. И, как в прошлый раз, файл должен быть в кодировке UTF-8.

Через неделю...

...нам надоест уже надоело вбивать капчу руками и мы воспользуемся антикапчей.

PS. Shelf Life theme.



Trackback URL for this post:

/trackback/368
Прикрепленный файл Размер
moemesto.php 4.31 кб
Дмитрий вт, 01/12/2019 - 17:51

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

Alek$ вт, 01/12/2019 - 18:51

В конце удет статья с ответами на все возникшие вопросы, в ней и напишу.
А общий ход мысли такой: Читаем файл с помощью функции file(), разбиваем строку на логин, емейл и пароль с помощью explode(), не забыв перед этим обрезать перевод строки в конце с помощью trim(). Потом в цикле for загружаем капчи, отображаем. На втором шаге так же в цикле отправляем запросы на дорегистрацию. Сохраняем результаты с помощью элементарных fopen(), fwrite(), fclose().

plotney чт, 14/01/2020 - 08:13

Пытаюсь писать авторег для yahoo.com, но никак немогу скопировать каптчу.
// При помощи простейшего регулярного выражения добываем сессионный ключ
name="captchaid" value="([a-f0-9]+)"
обьясни пожалуйсто как составляеться параметр VALUE

Alek$ чт, 14/01/2020 - 14:51

Я уже давал ссылку на хорошую статью по регулярным выражениям, по которой и сам их учил, и дам еще раз: http://docs.php.net/manual/ru/regexp.reference.php
Поле captchid есть в форме регистрации на МоеМесто, но у Яху другая форма, и вам нужно изучать ее. Как это делать - я тоже уже написал.

Herkules пн, 18/01/2020 - 22:47

Что-то у меня не получается, пишет повторите ввод каптчи. Такое впечатление, что мы грузим сначала страницу первый раз для получения каптчи, а потом если получили, то грузим ее второй раз и отправляем, то что добыли с первого раза, но каптча после перезагрузки страницы поменялась и выдает ошибку.

Alek$ пн, 18/01/2020 - 23:27

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

Herkules вт, 19/01/2020 - 02:46

Вот даю Вам ссылку http://kronson.hmsite.net/?p=42, код не влез в комменты. Провел небольшой тест, в котором показано что капчу (там параметр b) которую мы получили с рег1, вводим в рег2 где уже страница обновлена и там на ней другая капча.

Herkules вт, 19/01/2020 - 23:59

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

Alek$ ср, 20/01/2020 - 00:31

У вас там код по ссылке все равно побился. Дайте ссылку на проблемый сервис, я посмотрю, в чем может быть дело.

Aspiring сб, 04/12/2020 - 23:11

Зачем так писать?

register2($login, $email, $password, $_GET['captcha'], $_GET['key']) - почему бы тут вместо $_GET['key'] не поставить $key?

Alek$ вс, 05/12/2020 - 17:25

Потому что переменная $key извлекается из страницы до ввода капчи, а потом передается на второй шаг как часть запроса.



Отправить комментарий

CAPTCHA
Вы точно не бот?
3 + 9 =
Without JavaScript you won't pass captcha test, sorry. Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.