Как правильно отправить CURL запрос на сайт с капчей?

Всем добрый день! Помогите с такой задачей. Есть сайт, на нем для запроса данных надо ввести капчу, при каждом обновлении страницы капча конечно же обновляется, в body onload прописана js функция которая это делает. Мне надо получить капчу, отдать её пользователю, пользователь заполнил и отправить эти данные в форму. Получить капчу с помощью curl получается без проблем, делаю это вот так:
function request($url,$post = 0){
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url );
   curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36');
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул сервер
   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректами
   curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);// таймаут4
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
   curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt'); // сохранять куки в файл
   curl_setopt($ch, CURLOPT_COOKIEFILE,  dirname(__FILE__).'/cookie.txt');
   curl_setopt($ch, CURLOPT_POST, $post!==0 ); // использовать данные в post
   if($post)
       curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
   $data = curl_exec($ch);
   return $data;
}
$data = request('******');
include 'simple_html_dom.php';
$data = str_get_html($data);
foreach($data->find('img[id=captcha]') as $element) 
   {
      echo "<img src=\"*****/".$element->src."\" /><br>";
} 
$data->clear();
unset($data);

Вместо звездочки нужный мне сайт, капча выводится, но при следующем запросе который я делаю вот так:
function request($url,$auth){
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url ); // отправляем на
   curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36');
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул сервер
   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректами
   curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);// таймаут4
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
   curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt'); // сохранять куки в файл
   curl_setopt($ch, CURLOPT_COOKIEFILE,  dirname(__FILE__).'/cookie.txt');
   curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $auth);
   $data = curl_exec($ch);
   curl_close($ch);
   return $data;
}
$auth = "series=$seria&number=$number&answer=$captcha";
$data = request('******',$auth);
include 'simple_html_dom.php';
$data = str_get_html($data);
foreach($data->find('div[id=response]') as $element) 
   {
      echo $element->plaintext."<br>";
   } 
   foreach($data->find('div[id=error]') as $element2) 
   {
      echo $element2->plaintext."<br>";
   }

Соответственно делается новый запрос и мне уже приходит ответ что капча неверная. Есть ли возможность как то держать соединение открытым и второй запрос отправить без перезапуска страницы?
  • Вопрос задан
  • 3116 просмотров
Решения вопроса 1
@remzalp
Программер чего попало на чем попало
Сама идеология HTTP протокола в том, что каждый запрос независимый. Единственный костыль, который позволяет отследить состояние - cookie.

Вся последовательность работы:
1. скачать страницу с капчей
2. Тут же СКАЧАТЬ КАРТИНКУ КАПЧИ - вот тут у вас косяк, потому что вы отдаете урл картинки, она открывается другим браузером - у юзера, с другими куками и другим ип адресом, сохранить её в файл
3. отдать картинку юзеру с вашего локального сервера, получить от него текст капчи
4. текст капчи отпостить на форму из п.1

на всех этапах следим за куками. Wireshark/tcpdump в помощь, позволит заглянуть глубже некуда.

Функции request() из первого файла более чем достаточно, зачем костылить одноименную такую же функцию во втором случае?
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Sanasol
@Sanasol Куратор тега PHP
нельзя просто так взять и загуглить ошибку
Используйте curl_init один раз.
Затем все запросы через него, тогда не будетпотерь данных между сессиями.
Это костыльный вариант.

или так
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
Ответ написан
Ваш ответ на вопрос

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

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