【问题标题】:Checking for dead links locally in a static website (using wget?)在静态网站中本地检查死链接(使用 wget?)
【发布时间】:2018-08-23 00:08:16
【问题描述】:

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

  • <a href="some/file.pdf">file.pdf</a>等相关链接

  • 绝对链接,最有可能指向外部网站,例如<a href="http://example.com">example</a>

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

目前,我有一个基于通过python3 http.serve 运行本地网络服务器并通过 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


    【解决方案1】:

    所以我认为你的方向是正确的。我会使用wgetpython,因为它们是许多系统上两个现成的选项。好的部分是它可以为您完成工作。现在你想要的是从该进程的stdout 中监听Serving HTTP on 0.0.0.0

    所以我会使用下面的方法开始这个过程

    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
    

    【讨论】:

    • 我希望有一个更简单的解决方案,但缺少更简单的解决方案,这是干净有效的。谢谢。我暂时不接受答案,以防有人能找到更好的答案。
    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 1970-01-01
      • 2010-11-29
      • 2011-12-16
      相关资源
      最近更新 更多