【问题标题】:Get http-statuscode without body using cURL?使用 cURL 获取没有正文的 http-statuscode?
【发布时间】:2023-03-08 01:46:01
【问题描述】:

我想解析很多 URL 以仅获取它们的状态代码。

所以我做的是:

$handle = curl_init($url -> loc);
             curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
             curl_setopt($handle, CURLOPT_HEADER  , true);  // we want headers
             curl_setopt($handle, CURLOPT_NOBODY  , true);
             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
             $response = curl_exec($handle);
             $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
             curl_close($handle);

但是一旦将“nobody”选项设置为 true,返回的状态码就会不正确(google.com 返回 302,其他站点返回 303)。

由于性能损失,无法将此选项设置为 false。

有什么想法吗?

【问题讨论】:

  • 执行自定义请求并仅发出 HEAD。做一个全面的get也会转移身体。 head 只给你标题。
  • @MarcB 你能告诉我你的假设代码吗?
  • curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD')

标签: php performance curl http-status-codes


【解决方案1】:

curl 的默认 HTTP 请求方法是 GET。如果只需要响应头,可以使用 HTTP 方法HEAD

curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'HEAD');

根据@Dai 的回答,NOBODY 已经在使用 HEAD 方法。所以上面的方法是行不通的。

另一种选择是使用fsockopen 打开连接,使用fwrite 写入标头。使用fgets 读取响应,直到第一次出现\r\n\r\n 以获取完整的标头。由于您只需要状态码,因此您只需读取前 13 个字符。

<?php
$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
if ($fp) {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.google.com\r\n";
    $out .= "Accept-Encoding: gzip, deflate, sdch\r\n";
    $out .= "Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n";
    $out .= "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36\r\n";
    $out .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    $tmp = explode(' ', fgets($fp, 13));
    echo $tmp[1];
    fclose($fp);
}

【讨论】:

  • 所以我只需要添加此选项或删除已设置的选项之一?
  • 是的,在curl_exec之前添加。 HEAD 方法不包含响应正文,因此您可以删除 CURLOPT_NOBODY
  • 根据@Dai 的回答,它不会起作用。对不起。
  • 不幸的是,它的执行速度不如 CURLOPT_NOBODY 快(事实上,它似乎和没有 CURLOPT_NOBODY 和没有自定义请求一样慢)并且返回的状态代码仍然是错误的。 .
  • 试试上面的代码。它为 www.google.com 提供 302,而且速度也非常快。
【解决方案2】:

cURL 的 nobody 选项让它使用 HEAD HTTP 动词,我敢打赌大多数非静态 Web 应用程序我都没有正确处理这个动词,因此你看到的问题不同结果。我建议发出一个普通的GET 请求并丢弃响应。

【讨论】:

  • 问题在于性能——我需要连续执行数千个这样的请求。我还能做些什么来加快速度吗?
  • 便宜的多线程,将要检查的 url 数除以您拥有的内核数,每个内核运行一个脚本,执行 url 的子集
  • 你是对的......它没有帮助 php flush() 不起作用,因为服务器正在运行 nginx,因为这样我至少可以写出一些状态......跨度>
  • 奇怪的是,我刚刚发现,所有状态码 >= 400 都是正确的,因为这就是我所需要的,所以对我来说没问题...
  • 好的,这段代码非常快,但我的 URL 似乎不起作用 - 就像我使用应该返回 403 的 www.raffiniert.biz/kunden/coop_ch 一样,它什么也不返回, 如果 URL 有尾部斜杠?
【解决方案3】:

我建议改为get_headers()

<?php
$url = 'http://www.example.com';

print_r(get_headers($url));

print_r(get_headers($url, 1));
?>

【讨论】:

  • 根据我的测试,这还不如 cURL 快?
  • 好的,很高兴你对它进行了基准测试。留作将来参考。
  • 对不起,我想说:它比带正文的 cURL 快,但比不带正文的 cURL 慢(根据我的测试)。 YMMV
猜你喜欢
  • 2018-04-06
  • 2012-04-01
  • 2015-04-06
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
  • 2015-02-01
相关资源
最近更新 更多