7

描述底部的工作解决方案!

我正在运行 PHP 5.4,并试图获取 URL 列表的标题。

在大多数情况下,一切正常,但有三个 URL 会导致问题(并且可能更多,需要进行更广泛的测试)。

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

所有三个站点都可以在浏览器中正常工作,并产生以下标头响应:

(来自 Safari)

成功的标头

请注意,所有三个标头响应都是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,并且对解决方案不感兴趣CURLstream_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 都是无空格的,并且在各个方面都非常普通)

解决方案!

(感谢 Max 在下面的答案中为我指明了正确的轨道。)

问题是因为没有 pre-defined user_agent,既没有设置 in 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);

在此处找到用户代理更改。

4

1 回答 1

7

发生这种情况是因为所有这三个站点都在检查请求的 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函数将使用配置的值来完成。

于 2016-08-24T03:39:53.053 回答