获取网址列表的HTTP状态代码的脚本?


87

我有需要检查的URL列表,以查看它们是否仍然有效。我想写一个为我做的bash脚本。

我只需要返回的HTTP状态代码,即200、404、500等。而已。

编辑请注意,如果页面显示“ 404 not found”,但返回200 OK消息,则存在问题。这是配置错误的Web服务器,但您可能不得不考虑这种情况。

有关更多信息,请参阅检查URL是否转到包含文本“ 404”的页面。


2
公平地说,我的脚本的“错误”仅是在服务器返回HTTP代码200时,但正文文本显示为“ 404 not found”,这是Web服务器的行为异常。
Phil

2
如果响应代码为200,则wget的退出状态将为0,如果响应代码为404,则退出状态将为8,如果302为4,则退出状态...您可以使用$?变量以访问上一个命令的退出状态。
Casey Watson

Answers:


194

Curl--write-out为此有一个特定的选项:

$ curl -o /dev/null --silent --head --write-out '%{http_code}\n' <url>
200
  • -o /dev/null 扔掉通常的输出
  • --silent 丢掉进度表
  • --head 发出HEAD HTTP请求,而不是GET
  • --write-out '%{http_code}\n' 打印所需的状态码

要将其包装在完整的Bash脚本中:

#!/bin/bash
while read LINE; do
  curl -o /dev/null --silent --head --write-out "%{http_code} $LINE\n" "$LINE"
done < url-list.txt

(以鹰眼的读者会注意到,每个URL使用一个curl处理,这会施加fork和TCP连接惩罚。如果将多个URL合并在单个curl中,这样做会更快,但是没有空间写出怪异的重复进行卷曲所需的选项)。


非常好。我可以在文件中的每个URL上执行该命令吗?
Manu

1
@Manu:是的,我已经编辑了答案,以显示一种包装curl命令的可能方法。假设url-list.txt每行包含一个URL。
菲尔(Phil)

1
我不知道为什么从上面的脚本andswer总是让我在输出中得到000,但是当我只运行一次命令而没有循环时,它就起作用了……
Karol F

1
@KarolFiturski我遇到了同样的问题(您可能已经解决了这个问题,以防万一其他人跌跌撞撞...),在我的输入文件的行尾有回车符的情况下,导致网址像http://example.com/\r通过循环时
乔丹·罗宾逊

1
我遇到了这个问题,可以通过将结尾从Windows类型切换到Linux类型来解决此问题。
特里斯坦(Tristan)

38
wget --spider -S "http://url/to/be/checked" 2>&1 | grep "HTTP/" | awk '{print $2}'

只为您打印状态代码


9
+1重定向网址时显示多个代码,每个代码都位于新行。
Ashfame '04 -4-24

必须摆脱--spider才能使其与我尝试发出的请求一起使用,但是可以工作。
阿米塔夫克2015年

30

扩展Phil已经提供的答案。如果您使用xargs进行调用,那么在bash中添加并行性就可以了。

这里的代码:

xargs -n1 -P 10 curl -o /dev/null --silent --head --write-out '%{url_effective}: %{http_code}\n' < url.lst

-n1:仅使用一个值(来自列表)作为curl调用的参数

-P10随时保持10个卷曲过程活动(即10个并行连接)

检查write_out卷曲手册中的参数以获取更多可以使用它提取的数据(时间等)。

如果它对某人有帮助,这是我当前正在使用的电话:

xargs -n1 -P 10 curl -o /dev/null --silent --head --write-out '%{url_effective};%{http_code};%{time_total};%{time_namelookup};%{time_connect};%{size_download};%{speed_download}\n' < url.lst | tee results.csv

它只是将一堆数据输出到一个csv文件中,该文件可以导入到任何office工具中。


2
并行性,文件输入和csv。正是我想要的。
Agey 2013年

辉煌,成就了我的一天。
xlttj

这太棒了,正是我想要的,谢谢您,先生。一个问题,如何将页面的页面标题包含在csv结果中?
MitchellK

@estani - stackoverflow.com/users/1182464/estani一个怎么可能包括获得一个网页的页面标题为.csv文件。抱歉,转发不对,您忘记了标签,所以您会收到有关此问题的通知。非常感谢。
MitchellK

@MitchellK这根本不处理http调用的内容。如果网址中包含“页面标题”(无论是什么),则可以添加它。如果不是,则需要分析整个页面以提取其“标题”(假设您的意思是由http检索的html页面)。在堆栈溢出时寻找其他答案,或提出特定问题。
estani

15

这依赖于广泛可用的wget,甚至在Alpine Linux上几乎无处不在。

wget --server-response --spider --quiet "${url}" 2>&1 | awk 'NR==1{print $2}'

解释如下:

--quiet

关闭Wget的输出。

来源-wget手册页

--spider

[...]它不会下载页面,只需检查它们是否在那里。[...]

来源-wget手册页

--server-response

打印HTTP服务器发送的标头和FTP服务器发送的响应。

来源-wget手册页

他们没有说的--server-response是那些标头输出打印到标准错误(sterr),因此需要重定向到stdin。

将输出发送到标准输入,我们可以通过管道将awk其提取以提取HTTP状态代码。该代码是:

  • 第二个($2)非空白字符组:{$2}
  • 在标题的第一行: NR==1

并且因为我们要打印它{print $2}

wget --server-response --spider --quiet "${url}" 2>&1 | awk 'NR==1{print $2}'

1
我将其用于2>&1 | head -1 | awk '{ print $2 }'
Evhz

7

用于curl仅提取HTTP标头(而不是整个文件)并进行解析:

$ curl -I  --stderr /dev/null http://www.google.co.uk/index.html | head -1 | cut -d' ' -f2
200

当wget说404时,curl告诉我200 ... :(
Manu

-I标志使curl发出HTTP HEAD请求,某些服务器将其与普通HTTP GET分开处理,因此可以返回不同的值。没有该命令,该命令仍然可以运行。
lambshaanxy 2012年

4

wget -S -i *file* 将为您提供文件中每个URL的标题。

不过,请grep针对特定的状态代码进行过滤。


1

我发现了一个工具“webchk” Python编写的。返回一个状态代码的URL列表。 https://pypi.org/project/webchk/

输出看起来像这样:

▶ webchk -i ./dxieu.txt | grep '200'
http://salesforce-case-status.dxi.eu/login ... 200 OK (0.108)
https://support.dxi.eu/hc/en-gb ... 200 OK (0.389)
https://support.dxi.eu/hc/en-gb ... 200 OK (0.401)

希望有帮助!


0

由于https://mywiki.wooledge.org/BashPitfalls#Non-atomic_writes_with_xargs_-P(并行作业的输出xargs存在混合风险),我将使用GNU Parallel而不是xargs并行化:

cat url.lst |
  parallel -P0 -q curl -o /dev/null --silent --head --write-out '%{url_effective}: %{http_code}\n' > outfile

在这种特殊情况下,xargs由于输出太短了,所以使用起来可能是安全的,因此使用的问题xargs在于,如果以后有人更改代码以执行更大的操作,它将不再安全。或者,如果有人读了这个问题并认为他可以curl用其他东西代替,那可能也不安全。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.