Разница между командной строкой cURL и PHP cURL - PullRequest
5 голосов
/ 04 ноября 2019

У меня есть команда cURL, подобная этой:

curl 'https://www.11880.com' \
  -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36' \
  -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' \
  -H 'accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7' \
  -H 'authority: www.11880.com'

Выполнение этой команды в командной строке, как в приложении Terminal на моем Mac, приводит к ожидаемому выводу.

(В случае, если выпроверьте сами: если этот вывод содержит слово Sicherheitsüberprüfung, он геоблокирован, и вы должны использовать немецкий IP для его проверки.)

Я передал точную команду в PHP cURL следующим образом:

<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://www.11880.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers = array();
$headers[] = 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36';
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3';
$headers[] = 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7';
$headers[] = 'Authority: www.11880.com';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
curl_close($ch);
echo $result;
?>

Когда я запускаю этот код, я получаю сообщение о том, что мой запрос был распознан как автоматический запрос / робот: он говорит Sicherheitsüberprüfung, означает security check.

Конечно, яиспользование одного и того же IP-адреса как для командной строки, так и для запроса PHP cURL.

Почему это? Разве командная строка не совпадает с PHP cURL?

Или с моим PHP-скриптом что-то не так?

ОБНОВЛЕНИЕ

Я случайно обнаружилиз следующего: я использую Coda в качестве редактора кода на моем Mac. Это имеет встроенный движок рендеринга PHP. Используя это с моим сценарием PHP, результат, как и ожидалось. Это тот же результат, который я получаю в командной строке.

ОБНОВЛЕНИЕ 2

Я сделал то, что Jannes Botis предложил в его ответе. Затем я запустил скрипт PHP в своем приложении редактора кода Coda (с выводом ожидаемого) и с MAMP в качестве локального хоста (что всегда распознается как автоматический запрос).

Я выяснил, что код, выполняемый с помощью MAMP, былиспользуя HTTP/2, в то время как код, выполняемый в Coda, использует HTTP/1.1. Чтобы решить эту проблему, я добавил к сценарию следующее:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

Теперь оба выводят одну и ту же строку:

GET / HTTP/1.1
Host: www.11880.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Authority: www.11880.com

Но все равно: один работаетдругой распознается как автоматический запрос.

Ответы [ 3 ]

3 голосов
/ 07 ноября 2019

Попробуйте отладить запрос в обоих случаях:

a) Terminal : используйте curl verbose mode : curl -v и проверьте отправленный HTTP-запрос, особеннопроверить список заголовков

b) php curl : распечатать запрос http, используя CURLINFO_HEADER_OUT :

curl_setopt($ch, CURLINFO_HEADER_OUT, true);

curl_exec($ch);

$info = curl_getinfo($ch);
print_r($info['request_header']);

Тестирование различных заголовков, что сделаноэто работало, добавляя заголовок «Pragma: no-cache» к запросу:

$headers[] = 'Pragma: no-cache';

С другой стороны, в терминале curl мне приходилось вводить заголовки запроса в верхнем регистре, например, User-Agent и т. д.

Попробуйте создать tcp-соединение с fsockopen :

$fp = fsockopen("ssl://"."www.11880.com", 443, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.11880.com\r\n";
    $headers = array();
    $headers[] = 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36';
    $headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3';
    $headers[] = 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7';
    $headers[] = 'Authority: www.11880.com';
    $out .= $headers;
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 1024);
    }
    fclose($fp);

и проверьте, работает ли это. Возможно, проблема в том, что php curl добавляет некоторую информацию в запрос http или проблема на уровне соединения tcp, некоторая информация добавлена ​​туда.

Ссылки

1 голос
/ 13 ноября 2019

Командная строка curl :

Это инструмент для передачи данных на сервер или с сервера с использованием любого из поддерживаемых протоколов (HTTP, FTP, IMAP, POP3, SCP, SFTP, SMTP, TFTP, TELNET, LDAP или FILE). керл работает на Libcurl. Этот инструмент предпочтителен для автоматизации, так как он предназначен для работы без взаимодействия с пользователем. curl может передавать несколько файлов одновременно. Для более подробной информации о командной строке curl

Синтаксис:

curl [options] [URL...]

Пример:

curl http://site.{one, two,три} .com

PHP cURL

$ch = curl_init('http://example.com/wp-login.php');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);

if($this->getRequestType() == 'POST')
{
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 
        array(
            'user[name]'    => 'Generic+Username',
            'user[email]'   => 'mahekpatel04@gmail.com'
        );
    );
}

$response   = curl_exec($ch);
0 голосов
/ 08 ноября 2019

Проблема связана с шифрами, выбранными PHP cURL по умолчанию.

Запуск команды curl с параметрами -Ivs позволяет нам увидеть, какие шифры используются:

* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH

Настройкаони в PHP позволяют обойти эту загадочную проверку:

curl_setopt($ch,
  CURLOPT_SSL_CIPHER_LIST,
  'ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH'
);

Кроме того, кажется, что заголовок Host и использование HTTPv2 должны быть добавлены:

$headers[] = 'Host: www.11880.com';
// ...
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
...