Есть специалисты по cURL-у?

123 4
AutoBlogger
На сайте с 05.10.2011
Offline
121
2744

Собрался я пропарсить одну страничку, которая требует наличия куки (т.е. сначала нужно залогинится) и столкнулся с проблемой CURLOPT_FOLLOWLOCATION.

Как известно, на большинстве серверов curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); не работает, т.к. FOLLOWLOCATION считается потенциально небезопасной штукой. А как быть, если страничка, которую нужно вытянуть через cURL, доступна только через пару редиректов по 301 или 302.

Вот люди и придумали workaround: скрипты, которые сами последовательно пробегают по всем редиректам. Например такой:

function curl_flollow_exec($ch, $redirects = 0) {
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
$data = curl_exec($ch);

$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (($http_code == 301 || $http_code == 302) && ++$redirects < 10) {
preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches);
if (isset($matches[2])) {
$redirect_url = trim($matches[2]);
if ($redirect_url !== '') {
curl_setopt($ch, CURLOPT_URL, $redirect_url);
return curl_flollow_exec($ch, $redirects);
}
}
}
return $data;
}

function curl_post($url, $data, $set_cookie) {
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux i686; rv:16.0) Gecko/20100101 Firefox/16.0 Iceweasel/16.0');
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS);

$result = curl_flollow_exec($ch);
curl_close($ch);

return $result;
}

В 99 случаях из 100, этот метод прекрасно работает, но, к сожалению, не в моем. Скрипт нормально передает параметры login/password через POST. Сайт их прекрасно проглатывает и ставит нужную куку. Все бы вроде хорошо, но после последнего редиректа на нужную страницу, сервер вместо ее содержимого сообщает что, адрес неверный и того, что я ищу, там нет. Хотя с адресом все в порядке - если вбить его руками, то все нормально. Проблема возникает именно после редиректа через этот скрипт. Сессия, кстати, при этом тоже не отваливается (скрипт остается авторизованным).

Не могу понять, чего такого не хватает в вышеприведенном скрипте, что отличает результат его работы от обычного cURL с включенным CURLOPT_FOLLOWLOCATION (curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true))? Т.е, по идее, в обоих случаях результат должен быть одинаковым. А-н нет! cURL c curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true) срабатывает правильно и сервер выдает то, что нужно, а скрипт, эмулирующий FOLLOWLOCATION выдает 404.

Может кто знает, в чем может быть дело? Я себе уже все волосы на всех местах повыдергивал :(

🪄 www.cyberseo.net - плагин для создания автоблогов под WordPress, с поддержкой OpenAI GPT, Anthropic Claude, Google Gemini, Llama, Mistral, Midjourney, FLUX, Stable Diffusion | 📣 Импорт RSS / XML / JSON/ CSV / HTML
LEOnidUKG
На сайте с 25.11.2006
Offline
1769
#1

ну может быть вы эмуляторы тоже дадите покушать куков и реферов?

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/ ✅ Настройка и оптимизация серверов https://getmanyspeed.ru/
AutoBlogger
На сайте с 05.10.2011
Offline
121
#2

Так я и даю. Скрипт эмулятора я привел выше (попробуйте его на каком-нибудь примере). Куки он прекрасно создает и они лежат в CURLOPT_COOKIEJAR/CURLOPT_COOKIEFILE, как и положено. Авторизация происходит, последний редирект идет на правильный URL - все как надо. Только вместо контента нужной страницы, сервер выдает мне 404.

cURL со включенным CURLOPT_FOLLOWLOCATION и точно теми же параметрами (url, login, password) выдает правильный результат. Почему-то на том конкретном сайте спотыкается только эмулятор.

Я пытаюсь понять, чем работа эмулятора может отличаться от CURLOPT_FOLLOWLOCATION? Что в нем может быть не учтено?

bukachuk
На сайте с 07.09.2008
Offline
97
#3

Ну вы ответ сервера получите вместе с заголовками и посмотрите что там передают и как, эмулятор же по сути парсит заголовоки может там где ошибочка. Ну или если адрес куда идет редирект статичный - самому туда отправиться. Да и еще бывает что куки подменяют после авторизации. Вообщем если вы открываете один и тот же УРЛ и там даю 404 - значит проблему надо искать в cookiе и смотреть как они меняются в с включенным VERBOSE

Программирование PHP,Mysql (/ru/forum/934470)
AutoBlogger
На сайте с 05.10.2011
Offline
121
#4
bukachuk:
Ну вы ответ сервера получите вместе с заголовками и посмотрите что там передают и как, эмулятор же по сути парсит заголовоки может там где ошибочка.

Вот что отдает сервер после редиректов:

HTTP/1.1 404 Not Found

Cache-Control: no-cache, no-store, must-revalidate

Pragma: no-cache

Content-Type: text/html; charset=utf-8

Expires: -1

Server: Microsoft-IIS/7.5

Date: Mon, 04 Nov 2013 15:28:46 GMT

Content-Length: 7602

bukachuk:
Ну или если адрес куда идет редирект статичный - самому туда отправиться.

Если дергать его этим же эмулятором напрямую, то получается тот же 404 (см. выше). Если открыть в браузере или через cURL с включенным CURLOPT_FOLLOWLOCATION, то все нормально - выдает нужную страницу.

bukachuk:
Да и еще бывает что куки подменяют после авторизации.

Тогда cURL с CURLOPT_FOLLOWLOCATION тоже не помог бы. Но я повторюсь, когда сервер выдает 404, остается авторизованным. Более того, у страницке есть версия, которая доступна всем неавторизованным пользователям. Так вот, сервер и ее не отдает. Он тупо выкидывает 404.

bukachuk:
Вообщем если вы открываете один и тот же УРЛ и там даю 404 - значит проблему надо искать в cookiе и смотреть как они меняются в с включенным VERBOSE

Даже вообще без авторизации я должен получить версию страницы, доступную для всех. Но вместо нее я все равно получаю 404.

bukachuk
На сайте с 07.09.2008
Offline
97
#5

Ну чудес не бывает - Выводите пошагово какой URL Открывается в данный момент и смотрите, может вы открываете что не то или какой символ теряется да и включите VERBOSE

AutoBlogger
На сайте с 05.10.2011
Offline
121
#6

Вот пошагово (на входе URL и данные POST с логином и паролем):

HTTP/1.1 302 Found

Cache-Control: private

Content-Type: text/html; charset=utf-8

Location: [тут правильная ссылка на правильную страницу аккаунта, которая открывается в браузере, но дает 404 череp скрипт-эмулятор (см. следующий заголовок)]

Server: Microsoft-IIS/7.5

Set-Cookie: STGSHYTEFG=25E3CB014B2A73591CB930B244D8F2A8BFE; path=/; HttpOnly

Date: Mon, 04 Nov 2013 15:43:02 GMT

Content-Length: 137

HTTP/1.1 404 Not Found

Cache-Control: no-cache, no-store, must-revalidate

Pragma: no-cache

Content-Type: text/html; charset=utf-8

Expires: -1

Server: Microsoft-IIS/7.5

Date: Mon, 04 Nov 2013 15:43:02 GMT

Content-Length: 7586

Значит бывают чудеса, все же?

LEOnidUKG
На сайте с 25.11.2006
Offline
1769
#7

Там нигде случаем https не мелькает?

bukachuk
На сайте с 07.09.2008
Offline
97
#8

Надо сравнить VERBOSE с FOLLOW_LOCATION и этим эмулятором перехода, сравнить какие куки когда выдаются, какие адреса когда открываются итд то есть полностью два процесса сравнить логи. Да и ваше правильно подметили. Но логи вам это и покажут

AutoBlogger
На сайте с 05.10.2011
Offline
121
#9
LEOnidUKG:
Там нигде случаем https не мелькает?

Неа :(

FollowLocation
На сайте с 19.07.2013
Offline
12
#10

AutoBlogger, правильно ли передается реферер?

123 4

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий