この記事では、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') ...省略


