15

给定一个 url 列表,我想检查每个 url:

  • 返回 200 OK 状态码
  • 在 X 时间内返回响应

最终目标是一个能够将 url 标记为可能损坏的系统,以便管理员可以查看它们。

该脚本将用 PHP 编写,并且很可能每天通过 cron 运行。

该脚本一次将处理大约 1000 个 url。

问题有两部分:

  • 像这样的操作有什么大问题,你遇到了什么问题?
  • 考虑到准确性和性能,在 PHP 中检查 url 状态的最佳方法是什么?
4

9 回答 9

18

使用 PHP cURL 扩展。与 fopen() 不同,它还可以发出足以检查 URL 可用性并为您节省大量带宽的 HTTP HEAD 请求,因为您不必下载整个页面的正文进行检查。

作为起点,您可以使用如下函数:

function is_available($url, $timeout = 30) {
    $ch = curl_init(); // get cURL handle

    // set cURL options
    $opts = array(CURLOPT_RETURNTRANSFER => true, // do not output to browser
                  CURLOPT_URL => $url,            // set URL
                  CURLOPT_NOBODY => true,         // do a HEAD request only
                  CURLOPT_TIMEOUT => $timeout);   // set timeout
    curl_setopt_array($ch, $opts); 

    curl_exec($ch); // do it!

    $retval = curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200; // check if HTTP OK

    curl_close($ch); // close handle

    return $retval;
}

但是,有很多可能的优化:您可能想要重用 cURL 实例,如果每个主机检查多个 URL,甚至重用连接。

哦,这段代码确实严格检查 HTTP 响应代码 200。它不遵循重定向 (302)——但也有一个 cURL 选项。

于 2008-10-28T20:11:12.610 回答
6

查看卷曲。有一个 PHP 库。

还有一个 cURL 的可执行版本,因此您甚至可以用 bash 编写脚本。

于 2008-10-28T19:28:42.837 回答
4

实际上,我用 PHP 编写了一些东西,通过 5k+ URL 的数据库来执行此操作。我使用了 PEAR 类HTTP_Request,它有一个名为getResponseCode () 的方法。我只是遍历 URL,将它们传递给 getResponseCode 并评估响应。

但是,它不适用于 FTP 地址、不以 http 或 https 开头的 URL(未经证实,但我相信是这种情况)以及安全证书无效的站点(找不到 0)。此外,返回 0 表示未找到服务器(没有状态码)。

它可能比 cURL 更容易,因为您包含一些文件并使用单个函数来获取整数代码。

于 2008-10-28T19:32:37.757 回答
2
  1. fopen() 支持 http URI。
  2. 如果您需要更大的灵活性(例如超时),请查看 cURL 扩展。
于 2008-10-28T19:28:08.360 回答
1

似乎这可能是curl的工作。

如果您不拘泥于 PHP Perl 的 LWP 也可能是一个答案。

于 2008-10-28T19:33:47.130 回答
1

您还应该注意返回 301 或 302 HTTP 响应的 URL,这些响应重定向到另一个页面。通常这并不意味着链接无效。例如,http://amazon.com返回 301 并重定向到http://www.amazon.com/

于 2008-10-28T20:06:10.717 回答
1

仅仅返回 200 响应是不够的;许多有效链接在原所有者未能续订时,在变为色情/赌博门户后会继续返回“200”。

域名抢注者通常会确保其域中的每个 URL 返回 200。

于 2008-10-28T20:25:11.333 回答
0

您无疑会遇到的一个潜在问题是,当运行此脚本的机器失去对 Internet 的访问权限时……您将得到 1000 个误报。

您的脚本保留某种类型的历史记录并仅在失败 5 天后报告失败可能会更好。

此外,在继续进行标准检查之前,脚本应该以某种方式进行自我检查(例如检查已知良好的网站 [google?])。

于 2008-10-28T19:30:14.067 回答
0

您只需要一个 bash 脚本来执行此操作。请在此处查看我在类似帖子上的回答。它是一种单线器,可重用 HTTP 连接以显着提高速度,针对临时错误重试 n 次并遵循重定向。

于 2012-07-06T23:24:51.000 回答