Рабочий раствор внизу описания!
Я использую 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);
Обнаружено изменение агента пользователя Вот.
Это происходит потому, что все три этих сайта проверяют заголовок 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
Функция будет использовать настроенное значение.
Других решений пока нет …