get headers — `get_headers` возвращает & quot; 400 Bad Request & quot; и «403 Запрещено» для действительных URL?

Рабочий раствор внизу описания!

Я использую PHP 5.4 и пытаюсь получить заголовки списка URL-адресов.

По большей части все работает нормально, но есть три URL, которые вызывают проблемы (и, вероятно, больше, при более широком тестировании).

'http://www.alealimay.com'
'http://www.thelovelist.net'
'http://www.bleedingcool.com'

Все три сайта прекрасно работают в браузере и выдают следующие ответы в заголовках:

(Из сафари)

успешные заголовки

Обратите внимание, что все три ответа заголовка Code = 200

Но получение заголовков через PHP, используя get_headers

stream_context_set_default(array('http' => array('method' => "HEAD")));
$headers = get_headers($url, 1);
stream_context_set_default(array('http' => array('method' => "GET")));

… возвращает следующее:

url  ......  "http://www.alealimay.com"
headers
|    0  ............................  "HTTP/1.0 400 Bad Request"|    content-length  ...............  "378"|    X-Synthetic  ..................  "true"|    expires  ......................  "Thu, 01 Jan 1970 00:00:00 UTC"|    pragma  .......................  "no-cache"|    cache-control  ................  "no-cache, must-revalidate"|    content-type  .................  "text/html; charset=UTF-8"|    connection  ...................  "close"|    date  .........................  "Wed, 24 Aug 2016 01:26:21 UTC"|    X-ContextId  ..................  "QIFB0I8V/xsTFMREg"|    X-Via  ........................  "1.0 echo109"url  ......  "http://www.thelovelist.net"
headers
|    0  ............................  "HTTP/1.0 400 Bad Request"|    content-length  ...............  "378"|    X-Synthetic  ..................  "true"|    expires  ......................  "Thu, 01 Jan 1970 00:00:00 UTC"|    pragma  .......................  "no-cache"|    cache-control  ................  "no-cache, must-revalidate"|    content-type  .................  "text/html; charset=UTF-8"|    connection  ...................  "close"|    date  .........................  "Wed, 24 Aug 2016 01:26:22 UTC"|    X-ContextId  ..................  "aNKvf2RB/bIMjWyjW"|    X-Via  ........................  "1.0 echo103"url  ......  "http://www.bleedingcool.com"
headers
|    0  ............................  "HTTP/1.1 403 Forbidden"|    Server  .......................  "Sucuri/Cloudproxy"|    Date  .........................  "Wed, 24 Aug 2016 01:26:22 GMT"|    Content-Type  .................  "text/html"|    Content-Length  ...............  "5311"|    Connection  ...................  "close"|    Vary  .........................  "Accept-Encoding"|    ETag  .........................  "\"57b7f28e-14bf\""|    X-XSS-Protection  .............  "1; mode=block"|    X-Frame-Options  ..............  "SAMEORIGIN"|    X-Content-Type-Options  .......  "nosniff"|    X-Sucuri-ID  ..................  "11005"

Это имеет место независимо от изменения stream_context

//stream_context_set_default(array('http' => array('method' => "HEAD")));
$headers = get_headers($url, 1);
//stream_context_set_default(array('http' => array('method' => "GET")));

Выдает тот же результат.

Никаких предупреждений или ошибок не выдается ни для одного из них (обычно ошибки подавляются с помощью @get_headers, но нет никакой разницы в любом случае).

Я проверил мой php.ini, и имеют allow_url_fopen установлен в On,

Я направляюсь к stream_get_meta_data, и не заинтересован в CURL решения. stream_get_meta_data (и сопутствующие fopen) потерпит неудачу в том же месте, что и get_headersТаким образом, исправление одного исправит оба в этом случае.

Обычно, если есть перенаправления, вывод выглядит так:

url  ......  "http://www.startingURL.com/"
headers
|    0  ............................  "HTTP/1.1 301 Moved Permanently"|    1  ............................  "HTTP/1.1 200 OK"|    Date
|    |    "Wed, 24 Aug 2016 02:02:29 GMT"|    |    "Wed, 24 Aug 2016 02:02:32 GMT"|
|    Server
|    |    "Apache"|    |    "Apache"|
|    Location  .....................  "http://finishingURL.com/"|    Connection
|    |    "close"|    |    "close"|
|    Content-Type
|    |    "text/html; charset=UTF-8"|    |    "text/html; charset=UTF-8"|
|    Link  .........................  "; rel=\"https://api.w.org/\", ; rel=shortlink"

Почему сайты работают в браузерах, но не работают при использовании get_headers?

Существуют различные посты SO, обсуждающие одно и то же, но решение для всех из них не относится к этому случаю:

POST требует Content-Length (Я отправляю HEAD запрос, контент не возвращается)

URL содержит данные UTF-8 (Единственные символы в этих URL-адресах взяты из латинского алфавита)

Невозможно отправить URL с пробелами в нем (Все эти URL-адреса свободны и очень обычны во всех отношениях)

(Спасибо Максу в ответах ниже, что указал мне правильный путь.)

Проблема в том, что нет предопределенного user_agentбез установки в php.iniили объявив это в коде.

Итак, я меняю user_agent чтобы имитировать браузер, выполните действия, а затем верните его обратно к заявленному значению (вероятно, пусто).

$OriginalUserAgent = ini_get('user_agent');
ini_set('user_agent', 'Mozilla/5.0');

$headers = @get_headers($url, 1);

ini_set('user_agent', $OriginalUserAgent);

Обнаружено изменение агента пользователя Вот.

5

Решение

Это происходит потому, что все три этих сайта проверяют заголовок UserAgent запроса и отвечают с ошибкой в ​​том случае, если он не может быть сопоставлен. get_headers Функция не отправлять этот заголовок. Вы можете попробовать cURL и этот фрагмент кода для получения контента сайтов:

$url = 'http://www.alealimay.com';
$c = curl_init($url);
curl_setopt($c, CURLOPT_USERAGENT, 'curl/7.48.0');
curl_exec($c);
var_dump(curl_getinfo($c));

UPD:
Нет необходимости использовать cURL для установки заголовка пользовательского агента. Это также можно сделать с ini_set('user_agent', 'Mozilla/5.0'); а потом get_headers Функция будет использовать настроенное значение.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]