Как использовать Curl с HEADERS? - PullRequest
4 голосов
/ 02 марта 2012

Я пытался сделать что-то подобное, но это не работает!

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "http://google.com/"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('GET /search?q=kk HTTP/1.1
Host: www.google.de
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Proxy-Connection: Close
Cookie: PREF=ID=2bb051bfbf00e95b:U=c0bb6046a0ce0334:
Cache-Control: max-age=0
Connection: Close
'));
$response = curl_exec($ch); 
curl_close($ch);   



    echo $response;

Кроме того, возможно ли выполнить весь запрос только с заголовками без установки URL-адреса?Я имею в виду без этого?

curl_setopt($ch, CURLOPT_URL, "http://google.com/"); 

Спасибо!

Ответы [ 5 ]

4 голосов
/ 03 марта 2012

Чтобы добавить то, что сказали другие авторы, вы также не можете вставить команду GET в массив CURLOPT_HTTPHEADER, потому что это указано в других опциях cURL. cURL предназначен для работы с использованием функции curl_setopt; Вы не можете обойти это, поместив свое HTTP-сообщение в раздел заголовков. Например, чтобы убедиться, что ваша команда является операцией HTTP GET, вы устанавливаете CURLOPT_HTTPGET на TRUE (хотя по умолчанию cURL будет отправлять GET, пока вы не измените его на что-то другое).

Чтобы ответить на ваш вопрос о том, почему вы не можете получить правильный URL-адрес, вам нужно указать полное имя пути в CURLOPT_URL, а не только хост. Таким образом, вы действительно должны писать curl_setopt($ch, CURLOPT_URL, "http://google.de/search?q=kk HTTP/1.1");, чтобы установить URL.

Кроме того, я понятия не имею, почему вы поместили Connection: Close в заголовки HTTP для запроса GET. В этом заголовке вы говорите Google, что закрываете имеющееся у вас соединение .; это обрабатывается curl_close($ch);, так что забудьте об этом заголовке. На самом деле, половина элементов в ваших HTTP-заголовках не имеет места. Например, почему вы отправляете cookie в запросе для получения результатов поиска? Убедитесь, что вы знаете, что делает каждый заголовок, прежде чем отправлять его. В противном случае у вас нет абсолютно никакой возможности определить, отправляете ли вы правильные заголовки или нет.

4 голосов
/ 03 марта 2012

Я получил его на работу.

1) Измените заголовок Host: www.google.de на Host: www.google.com

Мотивация: хост, указанный в заголовке Host, должен точно соответствовать хосту URL.

2) Используйте "www.google.com" вместо "google.com"

Мотивация: поисковые запросы, отправленные на google.com, не будут получать результаты поиска.Вам будет предложено перейти на сайт www.google.com.

3) Установите полный URL-адрес в CURLOPT_URL, а не только имя хоста.Например, измените CURLOPT_URL на curl_setopt($ch, CURLOPT_URL, "http://www.google.com/search?q=kk");

Мотивация: правильное использование cURL API.

4) Удалите GET /search?q=kk HTTP/1.1 из CURLOPT_HTTPHEADER - он не на месте.

Мотивация: правильнаяиспользование cURL API.

5) Ответ будет сжат gzip или deflate.Чтобы остановить это, удалите заголовок запроса Accept-Encoding: gzip, deflate.

Мотивация: если вы скажете Google, что способны получать сжатый ответ, он отправит вам один.Распаковка HTTP-ответа - это дополнительный шаг, который вы, возможно, не захотите предпринять.Может быть легче иметь дело с ответом, если он находится в несжатом текстовом виде.

2 голосов
/ 03 марта 2012

У вас есть несколько проблем, но их должно быть легко решить.Во-первых, вы задаете хост в заголовке, отличный от хоста в URL-запросе, но, поскольку вы используете HTTP1.0, это все равно не нужно.

Во-вторых, каждая строка в HTTPHEADER вам нужна как отдельная вещь в массиве, и вы не включаете строку GET.

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
   'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2',
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language: en-gb,en;q=0.5',
    'Accept-Encoding: gzip, deflate',
    'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',
    'Proxy-Connection: Close',
    'Cookie: PREF=ID=2bb051bfbf00e95b:U=c0bb6046a0ce0334:',
    'Cache-Control: max-age=0',
    'Connection: Close'
));

(Вы явно украли это из Firefox,и еще старая версия, но мы позволим ей сдвинуться с места.) Наконец, да, вы должны указать CURLOPT_URL, именно так разработан API cURL.

1 голос
/ 02 марта 2012

В следующий раз вам следует внимательно прочитать руководство.Вот пример того, как добавить поля: array('Content-type: text/plain', 'Content-length: 100'), не все в одной строке, но поля являются отдельными элементами массива.

1 голос
/ 02 марта 2012

Если вам нужен такой высокий уровень контроля над получающимся HTTP-запросом, я бы рекомендовал использовать функции необработанных сокетов для ручной отправки запроса.В руководстве даже есть пример выполнения HTTP-запроса с помощью fsockets:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...