Python の標準ライブラリだけを使って HTML から特定のタグの中のテキストを抽出する方法について説明します。
一般的には Requests や BeautifulSoup などの便利なパッケージを使うのが確実でなおかつ早いですが、今回は標準ライブラリだけを使った方法を説明します。 追加のパッケージを入れられない・入れたくない何らかの事情がある場合は今回のようなアプローチをとることになるかと思います。
早速実際のコードです。
html.parser.HTMLParser
を使うと比較的かんたんに実装できます:
from html.parser import HTMLParser
def extract_title(html: str) -> str:
"""HTML から `title` タグの中身を抽出する"""
return TagTextExtractor('title').find(html)
class TagTextExtractor(HTMLParser):
"""指定されたタグの中身を抽出する"""
def __init__(self, tag: str):
HTMLParser.__init__(self)
self.tag = tag
self._in_region = False
self._text = ''
def find(self, html) -> str:
self._in_region = False
self._text = ''
super().feed(html)
text = self._text
self._in_region = False
self._text = ''
return text
def handle_starttag(self, tag, attrs):
if tag == self.tag:
self._in_region = True
def handle_endtag(self, tag):
if tag == self.tag:
self._in_region = False
def handle_data(self, data):
if self._in_region:
self._text += data
extract_title(html)
# => "Example Domain" など
HTML が手元に無い場合は先に urllib.request
で取得してこれば OK です:
import urllib.request
def fetch_html(url: str) -> str:
"""指定された URL の HTML を取得する"""
with urllib.request.urlopen(url) as response:
html = response.read().decode()
return html
extract_title()
と fetch_html()
は次のように組み合わせて使えます:
URLS = """https://example.com
https://wikipedia.org
https://apple.com
https://www.mozilla.org""".splitlines()
for url in URLS:
html = fetch_html(url)
title = extract_title(html)
print(f'{url} {title}')
# =>
# https://example.com Example Domain
# https://wikipedia.org Wikipedia
# https://apple.com Apple
# https://www.mozilla.org Internet for people, not profit — Mozilla