给定一个 url 列表,我想检查每个 url:
- 返回 200 OK 状态码
- 在 X 时间内返回响应
最终目标是一个能够将 url 标记为可能损坏的系统,以便管理员可以查看它们。
该脚本将用 PHP 编写,并且很可能每天通过 cron 运行。
该脚本一次将处理大约 1000 个 url。
问题有两部分:
- 像这样的操作有什么大问题,你遇到了什么问题?
- 考虑到准确性和性能,在 PHP 中检查 url 状态的最佳方法是什么?
使用 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 选项。
查看卷曲。有一个 PHP 库。
还有一个 cURL 的可执行版本,因此您甚至可以用 bash 编写脚本。
实际上,我用 PHP 编写了一些东西,通过 5k+ URL 的数据库来执行此操作。我使用了 PEAR 类HTTP_Request,它有一个名为getResponseCode () 的方法。我只是遍历 URL,将它们传递给 getResponseCode 并评估响应。
但是,它不适用于 FTP 地址、不以 http 或 https 开头的 URL(未经证实,但我相信是这种情况)以及安全证书无效的站点(找不到 0)。此外,返回 0 表示未找到服务器(没有状态码)。
它可能比 cURL 更容易,因为您包含一些文件并使用单个函数来获取整数代码。
似乎这可能是curl的工作。
如果您不拘泥于 PHP Perl 的 LWP 也可能是一个答案。
您还应该注意返回 301 或 302 HTTP 响应的 URL,这些响应重定向到另一个页面。通常这并不意味着链接无效。例如,http://amazon.com返回 301 并重定向到http://www.amazon.com/。
仅仅返回 200 响应是不够的;许多有效链接在原所有者未能续订时,在变为色情/赌博门户后会继续返回“200”。
域名抢注者通常会确保其域中的每个 URL 返回 200。
您无疑会遇到的一个潜在问题是,当运行此脚本的机器失去对 Internet 的访问权限时……您将得到 1000 个误报。
您的脚本保留某种类型的历史记录并仅在失败 5 天后报告失败可能会更好。
此外,在继续进行标准检查之前,脚本应该以某种方式进行自我检查(例如检查已知良好的网站 [google?])。
您只需要一个 bash 脚本来执行此操作。请在此处查看我在类似帖子上的回答。它是一种单线器,可重用 HTTP 连接以显着提高速度,针对临时错误重试 n 次并遵循重定向。