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 のインストールは以下。
beautifulsoup3 というのもあるらしいけれど Python 3.x には未対応という話も見かけた。素直に beautifulsoup4 を使うのがいいのだろう…。
html を読み込んで、リンクされてるファイル名を一覧で出力するスクリプトを、Google gemini 2.0 に生成してもらった。一部手直しはしたけれど、基本部分は gemini が生成したものがそのまま動いてくれた。
_htmlparse01.py
使い方は以下のような感じ。
HTML内の、以下の記述部分からファイル名を抽出して、一覧で出力してくれる。
出力結果は以下のような感じ。
これは便利だ…。後は Python からFTPサーバにアクセスできれば、修正したHTMLと関連ファイルを自動でアップロード、といったこともできるかもしれない。
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と関連ファイルを自動でアップロード、といったこともできるかもしれない。
[ ツッコむ ]
以上です。