サイト内のリンク切れを検出するプログラムを作成してみた

過去に貼ったリンクが切れているかを確認したいとき、自分でサイト巡回して、一つずつ手動で踏むのは面倒だと思います。なので自動化のためのプログラムを開発しました。

開発環境

  • OS:macOS 14.4
  • Python:3.11
  • 使用ライブラリ:beautifulsoup4 4.12.3 ,
  • 使用ライブラリ:requests 2.31.0

内部リンク編

とりあえず内部リンクが切れていないかのみを確認します。外部リンクは後ほどやります


使用ライブラリ

言語はPythonで、使用する外部ライブラリはrequestsBeautifulSoupです

requests

requestは、webページのhtmlを入手する時と、レスポンスを確認する時の2つの用途で使用します。

BeautifulSoup

BeautifulSoupは、HTMLやXMLのデータを解析して、データを抽出するためのライブラリです。

ここでは、requestsで入手したHTMLのコードから、aタグを抽出するのに使います。

処理の流れ

①requestsを使ってindex.htmlを取得

②BeautifulSoupを使って、index.html内の内部リンクおよび外部リンクを全て取得

③requestsのgetメソッドを使って、取得した内部リンク内にある、全ての内部リンクおよび外部リンクを取得

④新しい内部リンクを取得する毎に、③の処理を繰り返す(サイト内にある全ての内部リンクと外部リンクが格納されたリストが完成)

⑤取得した全ての内部リンクに対し、getを投げてレスポンスを確認する


......ん? これ、③ , ④で全ての内部リンクにgetリクエスト投げることになるから、⑤の手順要らなくない?って作ってる途中に思いましたが、

③はリンクを探す処理 で、
⑤は有効なリンクかチェックする処理

という感じで分けたかったのでちょっと冗長になりました許してください


また、内部リンクを調べるだけなら、外部リンクは取得する必要は無いですが、後ほど外部リンクも調べるのでココの手順で一緒に取得しちゃいます

ソースコード

get_links()が全ての内部リンクと外部リンクを取得する関数で、

confirmation()が、リンク切れかをチェックする関数です。

linksearch.py

実行すると、下記のように出力されました。

1,2行目が重複してる....( °Д° ) すみません!!

ブログ始めたてなので内部リンク数が少ないですが、無事に全ページのリンクがチェックされてます。v(´∀`*)ヤッター

外部リンク編

外部リンクのチェックも、基本的には内部リンクと同様にgetリクエストを投げれば良いだけなんですが、robots.txtに準拠する必要があります


詳しくは下の記事で解説していますが、要するにrobots.txtはクローラーに対する指示を記したファイルで、webサイトをクローリングする際は、このrobots.txtに従う必要があります。


処理の流れ

ということで処理の流れです。外部リンクのリスト(external_link)は前項で取得済みなので、それを前提とします。


①for文で外部リンクを一つずつ取り出す

②外部リンクから、/robots.txtを取得

③「User-agent: *」の項目にある「Allow」と、「Disallow」のpathを全て取得

④自分が走査したいpathと照合して,許可、不許可を確認

⑤許可されている場合、またはrobots.txtが存在しない場合に、getリクエストでチェック


ソースコード

is_allowed()が現在のリンクがrobots.txtで許可されてるか確認する関数です。

実行結果は下記のようになります。


twitterはクロールに厳しいですね.....
また、universe.roboflow.comは、 手動でクリックしたら生きていたので、robots.txtで許可されていても、サーバー側でbotを弾く設定をしていた場合は手動での確認が必要となってしまうみたいです

合体版

と言うわけで、以上の2つを合体して、一度の実行で、内部リンクと外部リンクの両方をチェックできるプログラムにします。


が、それをここに書くとソースコードが長くて埋まっちゃうので、gitにあげておきます。ぜひ自由に使ってみてください!

https://github.com/porosting/link-detection

まとめ

以上で、自動でサイト内のリンク切れを検出プログラムを作成することができました!これでサイト内のリンクが多くても多分大丈夫です!!