mieki256's diary



2025/04/02(水) [n年前の日記]

#1 [python] PythonでHTMLを解析したい

Pythonを使ってHTMLを解析できないものかと思い立った。HTML内でリンクされてるファイル名を取得して一覧で出力したい。ファイル名一覧が得られれば、それらのファイルをFTPサーバに自動でアップロードすることもできるようになるかもしれない。

Google gemini 2.0 に尋ねてみたら、beautiful soup というモジュールがメジャーだよ、サンプルコードはコレだよ、と言ってきた。気になる。試用してみようか…。

環境は、Windows10 x64 22H2 + Python 3.10.10。

beautiful soup のインストールは以下。
pip install beautifulsoup4

beautifulsoup3 というのもあるらしいけれど Python 3.x には未対応という話も見かけた。素直に beautifulsoup4 を使うのがいいのだろう…。

html を読み込んで、リンクされてるファイル名を一覧で出力するスクリプトを、Google gemini 2.0 に生成してもらった。一部手直しはしたけれど、基本部分は gemini が生成したものがそのまま動いてくれた。

_htmlparse01.py
import sys
import re
from bs4 import BeautifulSoup


usage_mes = "Usage: python htmlparse01.py <html_file_path> [sjis|shift_jis|utf8|utf-8]"


def extract_all_file_paths(html_file, charset):
    """
    ローカルHTMLファイルを読み込んで、
    href, img src, script src, CSS内ファイルパスを抽出する。

    Args:
        html_file (str): HTMLファイルのパス。
        charset (str): utf-8 or shift_jis

    Returns:
        tuple: href, img src, script src, CSS内ファイルパスのリストをタプルで返す
    """
    try:
        html = ""
        with open(html_file, "r", encoding=charset) as f:
            html = f.read()

        soup = BeautifulSoup(html, "html.parser")

        hrefs = [a["href"] for a in soup.find_all("a", href=True)]
        image_srcs = [img["src"] for img in soup.find_all("img", src=True)]
        script_srcs = [script["src"] for script in soup.find_all("script", src=True)]

        # スタイルシートファイルパスを抽出
        stylesheet_paths = []
        for link in soup.find_all("link", rel="stylesheet", href=True):
            stylesheet_paths.append(link["href"])

        for style in soup.find_all("style"):
            # styleタグ内のurl()関数で指定されたファイルパスを抽出
            urls = re.findall(r"url\(['\"]?([^'\")]+)['\"]?\)", style.text)
            stylesheet_paths.extend(urls)

        return hrefs, image_srcs, script_srcs, stylesheet_paths

    except FileNotFoundError:
        print(f"Error : Not found {html_file}")
        return [], [], [], []
    except Exception as e:
        print(f"Error : {e}")
        return [], [], [], []


def main():
    if len(sys.argv) == 2:
        html_file = sys.argv[1]
        charset = "utf-8"
    elif len(sys.argv) == 3:
        html_file = sys.argv[1]
        charset = sys.argv[2]
    else:
        print(usage_mes)
        sys.exit(1)

    if charset == "sjis":
        charset = "shift_jis"
    elif charset == "utf8":
        charset = "utf-8"

    hrefs, img_srcs, script_srcs, css_paths = extract_all_file_paths(html_file, charset)

    print("# href=")
    for href in sorted(list(set(hrefs))):
        print(href)

    print("# img src=")
    for src in sorted(list(set(img_srcs))):
        print(src)

    print("# script src=")
    for src in sorted(list(set(script_srcs))):
        print(src)

    print("# style src=")
    for path in sorted(list(set(css_paths))):
        print(path)


if __name__ == "__main__":
    main()

使い方は以下のような感じ。
python htmlparse01.py index_utf8.html utf8
python htmlparse01.py index_sjis.html sjis

HTML内の、以下の記述部分からファイル名を抽出して、一覧で出力してくれる。
<a href="xxx">
<img src="xxx">
<script src="xxx">
<style> h1 { background: url(xxx);}

出力結果は以下のような感じ。
> python htmlparse01.py test\index.html utf8
# href=
../index2.html
20241212/IMG_0161b.jpg
20241212/IMG_0164b.jpg
...
20250326/IMG_0020a.jpg
# img src=
20241212/IMG_0161b_thumb.jpg
20241212/IMG_0164b_thumb.jpg
...
20250326/IMG_0020a_thumb.jpg
# script src=
# style src=
img/logo1.gif

これは便利だ…。後は Python からFTPサーバにアクセスできれば、修正したHTMLと関連ファイルを自動でアップロード、といったこともできるかもしれない。

以上、1 日分です。

過去ログ表示

Prev - 2025/04 - Next
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project