我正在从 URL 列表中对网站执行链接检查,我能想到的唯一方法是使用 wget:,wget --server-response -i inputfile 2> output
然后进一步解析标头响应。这会为大型列表输出一个相对较大的文件,我只想知道是否存在 404。典型的响应如下所示:
--2017-03-28 19:14:39-- https://www.example.com/foo/bar
Reusing existing connection to www.example.com:443.
HTTP request sent, awaiting response...
HTTP/1.1 404 NotFound
<snip>
我如何才能对每个 url(来自 stderr)的 wget 输出执行正则表达式匹配,并且如果存在 404 则输出该 url,然后我可以将其重定向到一个文件,这样我就剩下一个包含 404 列表的文件?(请不要建议使用 curl,不幸的是该网站设置为返回METHOD NOT ALLOWED
。
答案1
怎么样
#!/bin/bash
URLLIST=/path/to/file
for each in `cat $URLLIST`
do
IS404=`wget -S "$each" -O /dev/null 2>&1 | grep "HTTP/1.1 404" | wc -l`
if [ $IS404 -gt 0 ]
then
echo $each
fi
done
我只对上述内容进行了部分测试,但关键行(以 IS404 开头)对每个 URL 执行 wget(因为它在 for each 循环中),丢弃输出,重定向标准输出(这就是 2>&1 所做的),因此将标头(感谢 -S)重定向到 stdout,然后计算 404 响应的数量。如果找到一个或多个,它会打印 URL。
答案2
抱歉,最初我错过了“不建议卷曲”警告。但你仍然可以从这篇文章中获得一些东西……
这样做的方法是使用卷曲. 如果你收到回复方法不允许,同样的答复必须包含允许的方法列表。你也许可以发布它。有时得到方法是不允许的,而头方法是允许的;其他时候,反之亦然。唯一知道的方法是检查答复。我的猜测你尝试过得到方法,并自动得出结论,头方法 (IE(仅下载标头)同样被禁止。不一定如此,有时管理员会禁止 GET 以避免其有限的连接资源过载,但他们会允许 HEAD。无法知道先验。
卷曲的优点:
卷曲可以告诉它只下载标题,从而放弃(在这种情况下)无用的实际页面下载;只需尝试:
curl -I http://www.debian.org
卷曲自动保持连接打开一段默认时间(900 秒,我思考):
# curl -v http:://www.debian.org -I www.debian.org ...... * Connection #0 to host www.debian.org left intact
这是默认选项,但为了安全起见,手册声明你可能如果你愿意,可以使用- 活着选项。
为了进一步加快速度,您可能希望并行化卷曲:
URL_LIST=$(cat inputfile)
echo $URL_LIST | xargs -n 1 -P 8 -I{} bash -c 'curl -I {} 2>1 | grep 404 &>/dev/null ; [ $? ] && echo {}'
这将逐个传递 URL 名称(-n 1)最多 8 个在平行下(-P 8)到以下命令,当且仅当404代码。选项-我{}告诉 xargs 将选定的 URL 名称放在何处。所有输出都将被丢弃,因为所需的只是最后一个命令的退出代码,grep。
根据您的具体需求,还有更多可能的调整:选项列表卷曲非常巨大。
答案3
你可以安装 powershell https://github.com/PowerShell/PowerShell
然后,您可以轻松编写一个强大的脚本来检查 URL 是否断开,并执行诸如发送电子邮件之类的操作: https://stackoverflow.com/questions/18500832/script-to-check-the-status-of-a-url
Foreach($Uri in $URLList) {
$error.Clear()
$time = Measure-Command { $request = Invoke-WebRequest -Uri $uri } 2>$null
if ($error.Count -eq 0) {
$time.TotalMilliseconds
} else {
$error[0].Exception.Response
}
}