php curl: как я могу эмулировать запрос get точно так же, как веб-браузер? - PullRequest
45 голосов
/ 14 марта 2010

есть сайты, которые, когда я открываю определенный запрос ajax в браузере, получают страницу с результатами, но когда я пытаюсь загрузить их с помощью curl, я получаю сообщение об ошибке от сервера.

как мне правильно эмулировать запрос get на сервер, который будет имитировать браузер?

вот что я делаю:

$url="https://new.aol.com/productsweb/subflows/ScreenNameFlow/AjaxSNAction.do?s=username&f=firstname&l=lastname";
ini_set('user_agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT
5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,$url);
$result=curl_exec($ch);
print $result;

Ответы [ 2 ]

65 голосов
/ 14 марта 2010

Вы уверены, что модуль curl учитывает ini_set ('user_agent', ...)? Существует опция CURLOPT_USERAGENT, описанная в http://docs.php.net/function.curl-setopt.
Может ли также быть файл cookie, проверенный сервером? Вы можете справиться с этим, используя CURLOPT_COOKIE, CURLOPT_COOKIEFILE и / или CURLOPT_COOKIEJAR.

edit: поскольку в запросе используется https, при проверке сертификата также может быть ошибка, см. CURLOPT_SSL_VERIFYPEER.

$url="https://new.aol.com/productsweb/subflows/ScreenNameFlow/AjaxSNAction.do?s=username&f=firstname&l=lastname";
$agent= 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)';

$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_URL,$url);
$result=curl_exec($ch);
var_dump($result);
0 голосов
/ 24 апреля 2019

я приведу пример, сначала решите, какой браузер вы хотите эмулировать, в этом случае я выбрал Firefox 60.6.1esr (64-bit) и проверите, какой запрос GET он выдает, это можно получить на простом сервере Netcat (MacOS объединяет Netcat, большинство дистрибутивов Linux объединяет Netcat, а пользователи Windows могут получить netcat от .. Cygwin.org, среди других мест),

настройка сервера netcat для прослушивания через порт 9999: nc -l 9999

теперь ударил http://127.0.0.1:9999 в Firefox, я получаю:

$ nc -l 9999
GET / HTTP/1.1
Host: 127.0.0.1:9999
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

Теперь давайте сравним это с простым скриптом:

<?php
$ch=curl_init("http://127.0.0.1:9999");
curl_exec($ch);

я получаю:

$ nc -l 9999
GET / HTTP/1.1
Host: 127.0.0.1:9999
Accept: */*

здесь есть несколько пропущенных заголовков, все они могут быть добавлены с параметром CURLOPT_HTTPHEADER curl_setopt, но вместо этого User-Agent должен быть специально установлен с помощью CURLOPT_USERAGENT (он будет постоянным при нескольких вызовах curl_exec (), и если вы используете Тогда CURLOPT_FOLLOWLOCATION будет сохраняться и при перенаправлении http), а вместо этого заголовок Accept-Encoding должен быть установлен с помощью CURLOPT_ENCODING (если они установлены с CURLOPT_ENCODING, то curl автоматически распакует ответ, если сервер решит сжать его, но если вы установите его с помощью CURLOPT_HTTPHEADER, затем вы должны вручную обнаружить и распаковать контент самостоятельно, что является болью в заднице и, вообще говоря, совершенно ненужным), так что добавляя их, мы получаем:

<?php
$ch=curl_init("http://127.0.0.1:9999");
curl_setopt_array($ch,array(
        CURLOPT_USERAGENT=>'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0',
        CURLOPT_ENCODING=>'gzip, deflate',
        CURLOPT_HTTPHEADER=>array(
                'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Language: en-US,en;q=0.5',
                'Connection: keep-alive',
                'Upgrade-Insecure-Requests: 1',
        ),
));
curl_exec($ch);

теперь, когда выполняется этот код, наш сервер Netcat получает:

$ nc -l 9999
GET / HTTP/1.1
Host: 127.0.0.1:9999
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Upgrade-Insecure-Requests: 1

и вуаля! наш php-эмулированный * GET-запрос теперь должен быть неотличим от реального GET-запроса Firefox:)

эта следующая часть просто придирчива, но если вы посмотрите очень внимательно, вы увидите, что заголовки расположены в неправильном порядке, Firefox поместит заголовок Accept-Encoding в строку 6, а наш эмулированный запрос GET поместит его в строка 3 .. чтобы исправить это, мы можем вручную поместить заголовок Accept-Encoding в правую строку,

<?php
$ch=curl_init("http://127.0.0.1:9999");
curl_setopt_array($ch,array(
        CURLOPT_USERAGENT=>'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0',
        CURLOPT_ENCODING=>'gzip, deflate',
        CURLOPT_HTTPHEADER=>array(
                'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Language: en-US,en;q=0.5',
                'Accept-Encoding: gzip, deflate',
                'Connection: keep-alive',
                'Upgrade-Insecure-Requests: 1',
        ),
));
curl_exec($ch);

при этом наш сервер netcat получает:

$ nc -l 9999
GET / HTTP/1.1
Host: 127.0.0.1:9999
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

проблема решена, теперь заголовки находятся даже в правильном порядке, и запрос выглядит так: ПОЛНОСТЬЮ НЕ УКАЗАН из реального запроса Firefox :) (я не рекомендую этот последний шаг, это бремя обслуживания, связанное с синхронизацией CURLOPT_ENCODING с пользовательским заголовком Accept-Encoding, и я никогда не сталкивался с ситуацией, когда порядок заголовков имеет большое значение)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...