HTML解析に使われるHTMLParserとは?BeautifulSoupについても解説

2024.01.04
html parser

HTML解析ができるHTMLParserを使ってみたいと思ったことはありませんか?

興味があっても、プログラムの知識を必要としていて、なんとなく難しそうですよね?

今回の記事では、HTMLParserに興味があるけれど、手を出しにくいという方のために

  • HTMLParserとは何か?
  • HTMLParserはどう使うのか?
  • Beautiful Soupとは何か?

などについて詳しく解説していきます。

この記事を読むことで、HTMLParserの基本的な使い方がわかるようになりますよ。ぜひ、最後まで読んでくださいね。

HTMLの解析とは?どんな時に使うもの?

そもそも、HTMLを解析するとはどういうことなのでしょうか?

Webサイト上にある特定のデータを抽出する技術をスクレイピングといいます。

データ収集やデータを分析・加工をすることで、新しいコンテンツを作りたいときなどにこの技術が使われます。

スクレイピングする上で必要となるものが、HTML文書の解析なのです。

こういったHTML文書の解析ができるものを総称してHTMLパーサーといいます。

HTMLパーサーは、HTML文書を解析して、プログラム内で扱いやすいデータに置き換える処理を行います

今回は、スクレイピングなどで利用されるHTMLパーサーについて、2つ紹介します。

  1. HTMLParserについて
  2. Beautiful Soupについて

どちらもPythonの実行環境があれば使えるライブラリです。

Beautiful Soupは外部ライブラリなので、インストールする必要がありますね。

HTMLParserについて

まずはHTMLParserの紹介をしていきます。

HTMLParserはPythonの標準ライブラリに含まれてるHTMLパーサーです。

HTML文書を読み込ませることにより、HTMLのタグを抽出したり、条件に合う属性のテキストを取得したりすることができます。

実はこの後に説明するBeautifulSoupでも、内部でHTMLParserを使うことができます。

BeautifulSoupの方が扱いやすいと言われますが、外部ライブラリを使いたくない場合などにHTMLParserは便利なライブラリです。

ここでは、HTMLParserの基本的な処理を3つお伝えします。

  1. HTMLタグをすべて解析
  2. 特定のタグのテキストを取得
  3. 特定の属性を持つタグのテキストを取得

それぞれ詳しく見ていきましょう。

HTMLタグをすべて解析

まずは、HTMLタグとデータを出力する例を紹介します。

HTMLタグをすべて解析
from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        print(f'開始タグ[{tag}]')

    def handle_endtag(self, tag):
        print(f'終了タグ[{tag}]')

    def handle_data(self, data):
        print(f'テキスト[{data}]')

parser = MyHTMLParser()
parser.feed('<html><head><title>HTMLParserの処理</title></head><body><h1>HTMLタグを解析</h1></body></html>')
実行結果

開始タグ[html]
開始タグ[head]
開始タグ[title]
テキスト[HTMLParserの処理]
終了タグ[title]
終了タグ[head]
開始タグ[body]
開始タグ[h1]
テキスト[HTMLタグを解析]
終了タグ[h1]
終了タグ[body]
終了タグ[html]

Pythonコードについて、上から解説していきますね。

1行目の「from html.parser import HTMLParser」にて、HTMLParserをインポートしています。

このHTMLParserを使うために独自クラスを作成します。

「class MyHTMLParser(HTMLParser):」を作成し、handle_starttag、handle_endtag、handle_dataというメソッドを使って、タグに応じた処理をオーバーライド(上書き)しています。

例えば、handle_starttagは、タグ開始にあわせて呼び出されるメソッドです。

こうした各メソッドの処理を実装することで、独自のパーサーを定義することができます。

最後のfeedメソッドが読み込まれたときに、定義したパーサーが実行されます。

解析する文章はfeedメソッドの第1引数に渡したHTML文書となります。

特定のタグのテキストを取得

続いて、HTMLタグの中で特定のタグのみを抽出するパーサーを作ってみます。

特定のタグのテキストを取得
from html.parser import HTMLParser
import re

class MyHTMLParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.parse_head = False
        self.headtag_text = []

    def handle_starttag(self, tag, attrs):
        if re.match('^h[1-9]$', tag):
           self.parse_head = True

    def handle_data(self, data):
        if self.parse_head:
            self.headtag_text.append(data)
            self.parse_head = False

parser = MyHTMLParser()
parser.feed('''
<h1>見出しの取得</h1>
<h2>1.特定のタグかどうか</h2>
<p>フラグで判断</p>
<h2>2.引数のdataをリストに保存</h2>
<h3>フラグを戻す</h3>
''')

print("\n".join(parser.headtag_text))
実行結果
見出しの取得
1.特定のタグかどうか
2.引数のdataをリストに保存
フラグを戻す

このコードでは、特定のタグ<h1>, … ,<h9>のテキストを抽出する処理を行っています。

MyHTMLParserクラスを定義して、handle_starttagの部分で、タグが<h1>, … ,<h9>のどれかであるか判定しています。

特定のタグであった場合、self.parse_headのフラグをTrueにしましょう。

handle_dataが呼び出されたときに、self.parse_headがTrueであれば、リストに加えていきます。

ここで、フラグをFalseに戻しておく必要がありますね。

最後にリストを1行ずつ出力することで、特定のタグのテキストを抽出することができます。

特定の属性を持つタグのテキストを取得

今度は、タグだけでなく、属性に対しても特定のものを抽出するパーサーを考えます。

特定の属性を持つタグのテキストを取得
from html.parser import HTMLParser
import re

class MyHTMLParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.parse_head = False
        self.headtag_text = []
        self.parse_class = ''

    def handle_starttag(self, tag, attrs):
        d = dict(attrs)
        if re.match('^h[1-9]$', tag) and self.parse_class in d.get('class', ''):
            self.parse_head = True

    def handle_data(self, data):
        if self.parse_head:
            self.headtag_text.append(data)
            self.parse_head = False

    def feed(self, content, class_=''):
        self.parse_class = class_
        super().feed(content)

parser = MyHTMLParser()
parser.feed('''
<h1>見出しの取得</h1>
<h2 class="grep">1.特定のタグかどうか</h2>
<p>フラグで判断</p>
<h2 class="grep">2.引数のdataをリストに保存</h2>
<h3>フラグを戻す</h3>
''', class_='grep')

print("\n".join(parser.headtag_text))
実行結果
1.特定のタグかどうか
2.引数のdataをリストに保存

HTML文書のタグが<h1>, … ,<h9>のものの中で、さらにclass属性がgrepのものを抽出する処理を書いています。

MyHTMLParserクラスの中で、今回はfeedメソッドの処理をオーバーライドしていますね。

class_に指定されている値をself.parse_classに代入して、feedを実行します。

feed
def handle_starttag(self, tag, attrs):
        d = dict(attrs)
        if re.match('^h[1-9]$', tag) and self.parse_class in d.get('class', ''):
            self.parse_head = True

attrsには、属性のデータが(属性名, 値) のペアでリストとして保存されています。

このattrsを辞書型に変換し、getメソッドで、属性名がclassのものを取得しています。

その中に先ほどのself.parse_classに代入した値があれば、Trueを返しましょう。

タグが<h1>, … ,<h9>かつ、class=”grep”であれば、self.parse_headがTrueになります

このフラグを利用して、handle_dataメソッドの部分で、テキストを保存するかどうかを判断します。

Beautiful Soupについて

HTMLParserに続いて、HTML文書のパーサーとして使えるPythonライブラリをもう1つ紹介します。

Beautiful Soupは、HTMLParserより短いコードで記述でき、簡単に目的のデータ取得ができます。

外部ライブラリなのでインストールする必要がありますね。

こちらのライブラリでも同じようにデータを取得してみましょう。

具体的に以下の2つの方法を試してみます。

  1. 特定のタグのテキストを取得
  2. 特定の属性を持つタグのテキストを取得

それぞれ説明していきましょう。

特定のタグのテキストを取得

まずは、特定のタグのテキストを取得する方法を紹介します。

特定のタグのテキストを取得
from bs4 import BeautifulSoup
html_doc = '''
<html>
<head>
<title>タイトル</title>
</head>
<body>
<h1>BeautifulSoupについて</h1>
<ul>
<li>インストールしてみよう</li>
<li>HTML文書を解析してみよう</li>
<li>色々な処理を試してみよう</li>
</ul>
</body>
</html>
'''
soup = BeautifulSoup(html_doc, 'html.parser')

print('title: ', soup.find('title').text)
print('h1: ', soup.find('h1').text)
print('li: ', soup.find('li').text)
実行結果
title:  タイトル
h1:  BeautifulSoupについて
li:  インストールしてみよう

「from bs4 import BeautifulSoup」でBeautifulSoupをインポートします。

bs4は、BeautifulSoupが入っているパッケージの名前です。

HTML文書をBeautifulSoupの第1引数に渡して、第2引数に使用するパーサーを指定するだけで解析をしてくれます。

soup.find(‘タグ名’)で、どのタグの要素を取得するか指定します。これに.textとつけることで、要素内のテキスト部分を取得できますよ。

実行結果のliタグを見るとわかると思いますが、soup.find(‘タグ名’)で取得できるものは最初の要素のみです。

すべての要素を取得したい場合は、以下のように記述してみてください。

すべての要素を取得
for element in soup.find_all("li"):
    print('li: ',element.text)

特定の属性を持つタグのテキストを取得

BeautifulSoupの場合でも、特定の属性を持つタグを取得できます。

特定の属性を持つタグのテキストを取得
from bs4 import BeautifulSoup

html_doc = '''
<html>
<head>
<title>タイトル</title>
</head>
<body>
<h1>BeautifulSoupについて</h1>
<ul>
<li>インストールしてみよう</li>
<li class="grep">HTML文書を解析してみよう</li>
<li class="grep">色々な処理を試してみよう</li>
</ul>
</body>
</html>
'''
soup = BeautifulSoup(html_doc, 'html.parser')
for element in soup.find_all("li", {'class': 'grep'}):
    print(element.text)
実行結果
HTML文書を解析してみよう
色々な処理を試してみよう

soup.find_allの第2引数に{属性名, 値}を足すことで、特定の属性を持つ要素を取得できます。

上記では、class名がgrepのli要素をすべて取得しています。


未経験でも確実にプログラミングスキルを身につけられる!
【DMM WEBCAMP】では、専属コーチが卒業まで伴走します!

短期間効率的にプログラミングスキルを身につけたい
✔プログラミングを独学で進めていくのが不安
✔家での時間を有効に使ってスキルアップがしたい
といった方におすすめです!

実践的なスキルが身に付くカリキュラム

まとめ:HTMLParserを使って様々な実装を試してみよう

今回は、HTMLParserの基本的な使い方について説明してきました。

Pythonの環境が必要となりますが、HTMLParserを使うとHTML文書の中の特定のデータ抽出ができるということがわかっていただけたでしょうか。

同じようなパーサーとして、Beautiful Soupについても解説させていただきました。

基本を覚えれば、コードを書き換えるだけで、様々なデータを抽出することができるようになりますよ。

今回の記事が少しでも参考になれば幸いです。


【DMM WEBCAMP】は受講生の97%が未経験からのスタート!
充実のサポート体制で、プログラミングスキルを確実に身につけられます!

✔一人ひとりに合わせた学習計画で進められるため、仕事や学校と両立できる
✔未経験者のために開発された実践的なカリキュラムを用意
✔︎専属コーチが卒業まで学習をサポート

目的別で選べる3つのコース

\プログラミングスクールを比較/

DMM WEBCAMP

COACHTECH

RUNTEQ

DMM WEBCAMP COACHTECH RUNTEQ
目指せる姿 WEBエンジニアへの転職
フリーランスエンジニア WEBエンジニアへの転職
分割払い
補助金 ×
転職保証 × ×
受講期間 12週間〜 3ヶ月〜 5ヶ月〜
特徴 【IT業界の転職を一番に考えたい方向け】
大手DMMが運営のプログラミングスクール
転職成功率98.8%
豊富なキャンペーンや補助金制度あり
【フリーランスを目指したい方向け】
フリーランスのエンジニアを最短で目指す
エンジニアと共に実際の案件開発を担当
【とことん勉強してから転職したい方向け】
1,000時間(約9カ月)のカリキュラムでしっかり勉強
企業の求める即戦力のWEBエンジニアを目指す
料金 329,350円〜
※給付金適用後
42万9,000円~ 55万円

公式HP

公式HP

公式HP

関連記事

資料請求

  • 短期集中で最速エンジニア転職を実現-転職成功者インタビュー一覧

    DMM WEBCAMPでは転職成功率98%を実現しています。本資料では、元警察官や元ラーメン屋など様々なバックグラウンドを持つ卒業生の声をお届けします。

    資料をダウンロードする
  • IT技術がもたらす3つの変化と身につけるべきスキル

    IT技術の発展により、今後10~20年程度で47%の仕事がなくなると言われています。どのような変化が訪れ、私達はどのようなスキルを身につけるべきかを解説します。

    資料をダウンロードする
  • 未経験がフリーランスエンジニアになる方法-年収アップで自由な働き方を手に入れる

    働き方改革やリモートワークの影響でフリーランスという働き方の人気は高まりつつあります。フリーランスエンジニアとして活躍するために必要な情報をお届けします。

    資料をダウンロードする

© 2024 WEBCAMP MEDIA Powered by AFFINGER5