この記事では、Python の標準モジュールである html.parserモジュール の HTMLParserクラス を使ってHTML文字列を解析する方法を解説します。
HTMLParser
を使うことでタグのタグ名や属性、タグ内の要素を取得することができます。
それでは、HTMLParser の使い方を見ていきましょう!
HTMLParseの使い方
HTML文字列を解析するには、html.parser
モジュール の HTMLParser
クラス を使うと簡単です。HTMLParser
クラス は継承して使用します。
from html.parser import HTMLParser
class MyParser(HTMLParser):
# 処理
HTMLParserのインスタンスは、HTML文字列が入力されるとタグなどの要素を見つけるたびにハンドラーメソッドを呼び出しますが、デフォルトのままでは特に何も処理されないのでサブクラスを定義し、ハンドラーメソッドを上書きする必要があります。
ハンドラーメソッド
派生クラス内でハンドラーメソッドを上書きしてタグを見つけた際の処理を定義します。
例えば、開始タグを見つけた場合は、handle_starttag()
メソッド が呼び出されます。
from html.parser import HTMLParser
class MyParser(HTMLParser):
# 開始タグを扱うメソッド
def handle_starttag(self, tag, attrs):
pass
tag
引数 には、小文字に変換されたタグの名前が格納されており、attrs
引数 には、そのタグの属性が (name, value)
の形でリストとして格納されています。
他にも終了タグを見つけた際に実行される handle_endtag()
メソッド やタグ内の要素を扱う handle_data()
メソッド など色々なハンドラーメソッドが定義されています。
LinkHTMLParser メソッド - html.parser--- HTML および XHTML のシンプルなパーサー — Python ドキュメント
例えば、タグ名と属性を出力するだけなら以下のように上書きします。
class MyParser(HTMLParser):
# 開始タグを扱うメソッド
def handle_starttag(self, tag, attrs):
print(f'開始タグ: {tag}')
for attr in attrs:
print(f'\t属性: {attr}')
パーサーにデータを入力する
パーサーにデータを入力するには feed()
メソッド を使います。feed()
メソッド にHTML文字列を渡すことで処理が開始されます。
parser = MyParser()
parser.feed(HTML文字列)
試しに簡単なHTMLデータから開始タグと属性を出力してみます。
from html.parser import HTMLParser
class MyParser(HTMLParser):
# 開始タグを扱うメソッド
def handle_starttag(self, tag, attrs):
print(f'開始タグ: {tag}')
for attr in attrs:
print(f'\t属性: {attr}')
# HTML文字列
html = '''<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>サイトタイトル</title>
</head>
<body>
<h1>タイトル</h1>
<h2>見出し2</h2>
<p>コンテンツの内容</p>
</body>
</html>'''
# パーサー生成
parser = MyParser()
# パーサーにデータを入力
parser.feed(html)
実行結果
開始タグ: html
属性: ('lang', 'ja')
開始タグ: head
開始タグ: meta
属性: ('charset', 'utf-8')
開始タグ: title
開始タグ: body
開始タグ: h1
開始タグ: h2
開始タグ: p
URLから解析
URLからHTML文字列を取得して解析することもできます。
import requests
from html.parser import HTMLParser
# 適当なURL
url = 'https://yumarublog.com/python/str'
# Webページを取得
r = requests.get(url)
class MyParser(HTMLParser):
# 開始タグを扱うメソッド
def handle_starttag(self, tag, attrs):
print(f'開始タグ: {tag}')
for attr in attrs:
print(f'\t属性: {attr}')
# パーサー生成
parser = MyParser()
# パーサーにデータを入力
parser.feed(r.text)
実行結果
開始タグ: html
属性: ('lang', 'ja')
開始タグ: head
属性: ('prefix', 'og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#')
開始タグ: meta
属性: ('charset', 'utf-8')
開始タグ: meta
属性: ('http-equiv', 'X-UA-Compatible')
属性: ('content', 'IE=edge')
開始タグ: meta
属性: ('name', 'viewport')
属性: ('content', 'width=device-width, initial-scale=1')
開始タグ: meta
属性: ('property', 'og:type')
属性: ('content', 'blog')
...省略