0

Как отправить куки с помощью PHP cURL в дополнение к CURLOPT_COOKIEFILE?

9

Описание проблемы:

Я занимаюсь парсингом контента с веб-сайта после отправки формы, однако мой скрипт иногда не работает, например, в 2 из 5 случаев он терпит неудачу. Я использую PHP cURL, а также COOKIEFILE и COOKIEJAR для обработки куки. При сравнении заголовков, отправляемых моим браузером (когда я посещаю целевой сайт и использую live http headers), и заголовков, отправляемых через PHP, я заметил множество различий.

Мой браузер отправляет гораздо больше переменных куки, чем PHP cURL. Я предполагаю, что это связано с тем, что большинство куки устанавливаются с помощью JavaScript, но я не уверен в этом.

Я использую следующий код для парсинга и показываю заголовки, отправляемые моим браузером и PHP cURL:

$ckfile = tempnam ("/tmp", 'cookiename');

$url = 'https://www.domain.com/firststep';
$poststring = 'variable1=4&variable2=5';
$ch = curl_init ($url);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $poststring);
$output = curl_exec ($ch);
curl_close($ch);

$url = 'https://www.domain.com/nextstep';
$poststring = 'variableB1=4&variableB2=5';
$ch = curl_init ($url);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $poststring);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$output = curl_exec ($ch);
$headers = curl_getinfo($ch, CURLINFO_HEADER_OUT);
curl_close($ch);

print_r($headers);

При этом вывод заголовков выглядит так:

POST /path HTTP/1.1
User-Agent: Mozilla
Host: domain.subdomain.nl
Accept: */*
Cookie: JSESSIONID=7BC2A5277A4EB07D9A7237A707BE1366; www-20480=MIFBNLFDFAAA
Content-Length: 187
Content-Type: application/x-www-form-urlencoded

А заголовки, полученные с помощью live http headers, выглядят намного более полными.

Вопросы:

  1. Делаю ли я что-то неправильно с обработкой куки в текущем коде, за исключением того, что PHP cURL отправляет очень мало переменных куки по сравнению с браузером? Могут ли другие различия между заголовками, отправляемыми браузером и PHP cURL, повлиять на получение правильного контента?

  2. Не отправляются ли некоторые переменные куки из-за того, что они устанавливаются JavaScript-ом?

  3. Как лучше всего обрабатывать куки, чтобы гарантировать, что все необходимые куки отправляются на удаленный сервер?

Буду признателен за любую помощь!

3 ответ(ов)

0

Если куки создаются через скрипт, вы можете отправить куки вручную вместе с куками из файла (используя опцию cookie-file). Например:

# отправка вручную установленного кука
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cookie: test=cookie"));

# отправка куков из файла
curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);

В этом случае cURL отправит ваш определенный куки вместе с куками из файла.

Если куки генерируются через JavaScript, вам нужно выяснить, как они создаются, а затем вы сможете отправить их с помощью вышеописанного метода (через HTTP-заголовок).

Куки utma, utmc, utmz наблюдаются, когда куки отправляются из Mozilla. Не стоит беспокоиться об этом.

В конце концов, то, что вы делаете, совершенно правильно. Просто убедитесь, что вы используете абсолютный путь к файлам (например, /var/dir/cookie.txt), а не относительный.

Всегда включайте режим подробного вывода при работе с cURL. Это очень поможет в отслеживании запросов и сэкономит вам много времени.

curl_setopt($ch, CURLOPT_VERBOSE, true);
0

Вы можете найти список примеров отправки cookies по следующей ссылке: php-curl-cookbook.

Вот пример кода, который демонстрирует, как использовать cURL для отправки cookies:

$curlHandler = curl_init();

curl_setopt_array($curlHandler, [
    CURLOPT_URL => 'https://httpbin.org/cookies',
    CURLOPT_RETURNTRANSFER => true,
    
    CURLOPT_COOKIEFILE  => $cookieFile, // файл с cookies
    CURLOPT_COOKIE => 'foo=bar;baz=foo', // отправляемые cookies

    /**
     * Либо можно установить заголовок
     * CURLOPT_HTTPHEADER => [
     *     'Cookie: foo=bar;baz=foo',
     * ]
     */
]);

$response = curl_exec($curlHandler);
curl_close($curlHandler);

echo $response;

В этом примере мы инициируем cURL, устанавливаем необходимые параметры, включая URL, флаг возврата результата и cookies, которые хотим отправить. Также есть возможность передать cookies через заголовок Cookie. После выполнения запроса мы закрываем обработчик cURL и выводим ответ.

0

Ваш код выполняет POST-запрос к API с использованием cURL и управляет файлами cookie. Вот шаги, которые вы выполняете:

  1. Создание файла cookie: Проверяете, существует ли файл cookies.txt. Если нет, создаёте его:

    $cookieFile = "cookies.txt";
    if(!file_exists($cookieFile)) {
        $fh = fopen($cookieFile, "w");
        fwrite($fh, "");
        fclose($fh);
    }
    
  2. Инициализация cURL: Создаёте сессию cURL и задаёте необходимые параметры:

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $apiCall);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // Использование файла cookie
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // Сохранение ответов в файл cookie
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    
  3. Выполнение запроса: Выполняете запрос и обрабатываете возможные ошибки:

    if(!curl_exec($ch)){
        die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
    }
    else{
        $response = curl_exec($ch); 
    }
    
  4. Закрытие cURL: Закрываете соединение cURL после выполнения запроса:

    curl_close($ch);
    
  5. Обработка и вывод результата: Декодируете JSON-ответ и выводите его на экран:

    $result = json_decode($response, true);
    echo '<pre>';
    var_dump($result);
    echo'</pre>';
    

Обратите внимание на то, что вы дважды вызываете curl_exec($ch), что может быть ошибкой. Вам следует сохранить результат одного вызова и затем обрабатывать его. Вот исправленный вариант:

$response = curl_exec($ch);
if($response === false) {
    die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}

Эти изменения помогут избежать ненужного выполнения запроса дважды и streamline вашу функцию.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь