在静态网站中本地检查死链接(使用 wget?)

问题描述 投票:0回答:2

wget --spider
是一个非常好的检查死链接(例如指向 404 错误的链接)的工具。但是,我有一个稍微不同的用例,我生成一个静态网站,并希望在上传之前检查损坏的链接。更准确地说,我想检查两者:

  • 相关链接如

    <a href="some/file.pdf">file.pdf</a>

  • 绝对链接,最有可能指向外部网站,例如

    <a href="http://example.com">example</a>

我尝试了

wget --spider --force-html -i file-to-check.html
,它读取本地文件,将其视为 HTML 并跟踪每个链接。不幸的是,它无法处理本地 HTML 文件中的相对链接(错误显示为
Cannot resolve incomplete link some/file.pdf
)。我尝试使用
file://
wget
不支持它。

目前,我有一个基于通过

python3 http.server
运行本地网络服务器并通过 HTTP 检查本地文件的 hack:

python3 -m http.server &
pid=$! 
sleep .5
error=0
wget --spider -nd -nv -H -r -l 1 http://localhost:8000/index.html || error=$? 
kill $pid
wait $pid
exit $error

出于以下几个原因,我对此并不满意:

  • 我需要这个

    sleep .5
    来等待网络服务器准备就绪。如果没有它,脚本就会失败,但我不能保证 0.5 秒就足够了。我希望有一种方法可以在服务器准备就绪时启动
    wget
    命令。

  • 相反,这个

    kill $pid
    感觉很丑。

理想情况下,

python3 -m http.server
可以选择在服务器准备就绪时运行命令,并在命令完成后自行关闭。这听起来可以通过编写一些 Python 来实现,但我想知道是否存在更干净的解决方案。

我错过了什么吗?有更好的解决方案吗?我在问题中提到

wget
是因为它几乎满足了我的要求,但使用
wget
对我来说不是必需的(
python -m http.server
也不是)。我只需要一些在 Linux 上易于运行和自动化的东西。

python hyperlink http-status-code-404 wget
2个回答
11
投票

所以我认为你正在朝着正确的方向前进。我会使用

wget
python
,因为它们是许多系统上两个随时可用的选项。好的部分是它可以为您完成工作。现在您想要的是从该过程的
Serving HTTP on 0.0.0.0
中聆听
stdout

所以我会使用如下所示的方式开始该过程

python3 -u -m http.server > ./myserver.log &

注意

-u
我在这里使用了无缓冲输出,这非常重要

现在接下来等待这段文字出现在

myserver.log

timeout 10 awk '/Serving HTTP on 0.0.0.0/{print; exit}' <(tail -f ./myserver.log)

所以

10
秒是您在这里的最长等待时间。休息是不言自明的。接下来关于你的
kill $pid
。我不认为这是一个问题,但如果你希望它更像用户的操作方式,那么我会将其更改为

kill -s SIGINT $pid

这相当于您在启动程序后处理

CTRL+C
。另外,我也会使用类似下面的内容来处理
SIGINT
我的 bash 脚本

https://unix.stackexchange.com/questions/313644/execute-command-or-function-when-sigint-or-sigterm-is-send-to-the-parent-script/313648

上面基本上将以下内容添加到 bash 脚本的顶部,以处理您使用

CTRL+C
或外部终止信号

终止脚本
#!/bin/bash
exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    trap - SIGINT SIGTERM # clear the trap
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

trap exit_script SIGINT SIGTERM

0
投票

Tarun Lalwani 的答案是正确的,按照那里给出的建议,可以编写一个干净而简短的 shell 脚本(依赖于 Python 和 awk)。另一个解决方案是完全用 Python 编写脚本,给出一个稍微冗长但可以说更干净的脚本。可以在线程中启动服务器,然后执行检查网站的命令,最后关闭服务器。我们不需要解析文本输出,也不需要再向外部进程发送信号。因此,脚本的关键部分是:

def start_server(port,
                 server_class=HTTPServer,
                 handler_class=SimpleHTTPRequestHandler):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    thread = threading.Thread(target=httpd.serve_forever)
    thread.start()
    return httpd

def main(cmd, port):
    httpd = start_server(port)
    status = subprocess.call(cmd)
    httpd.shutdown()
    sys.exit(status)

我编写了一个稍微更高级的脚本(在此基础上进行了一些命令行选项解析)并将其发布为:https://gitlab.com/moy/check-links

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.