я приведу пример,
сначала решите, какой браузер вы хотите эмулировать, в этом случае я выбрал 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, и я никогда не сталкивался с ситуацией, когда порядок заголовков имеет большое значение)