Python
 Computer >> コンピューター >  >> プログラミング >> Python

PythonでHTMLを解析する方法|html.parserモジュールによるカスタムパーサーの作り方

Pythonには、html.parserモジュールに含まれるHTMLParserクラスを使ってHTMLファイルを処理する機能が標準で備わっています。このクラスを利用することで、HTMLタグの種類やタグの位置など、さまざまな属性情報を検出できるだけでなく、HTMLファイル内に含まれるデータを識別して取得することも可能です。

以下の例では、HTMLParserクラスを継承したカスタムパーサークラスを作成し、クラス内で定義したタグやデータだけを処理する方法を紹介します。ここでは「開始タグ」「終了タグ」「データ」の3種類のイベントを処理します。

処理対象となるHTMLファイル

まず、Pythonのカスタムパーサーで処理するHTMLファイルは以下のとおりです。

例:test.html

<html>
<head>
<title>welcome to Tutorials Point!</title>
</head>
<body>
<h1>Learn anything !</h1>
</body>
</html>

カスタムパーサーの実装コード

続いて、上記のHTMLファイルを読み込み、独自のルールに従って結果を出力するパーサープログラムです。handle_starttag()handle_endtag()handle_data()は、それぞれ開始タグ・終了タグ・テキストデータが検出されたタイミングで自動的に呼び出されるコールバックメソッドです。また、getpos()メソッドを使うことで、現在処理中の行番号とオフセット(列位置)を取得できます。

例:custom_parser.py

from html.parser import HTMLParser
import io

class Custom_Parser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        print("Line and Offset ==", HTMLParser.getpos(self))
        print("Encountered a start tag:", tag)

    def handle_endtag(self, tag):
        print("Line and Offset ==", HTMLParser.getpos(self))
        print("Encountered an end tag :", tag)

    def handle_data(self, data):
        print("Line and Offset ==", HTMLParser.getpos(self))
        print("Encountered some data :", data)

parser = Custom_Parser()

stream = io.open("E:\\test.html", "r")
parser.feed(stream.read())

ポイントとして、parser.feed()メソッドに読み込んだHTML文字列を渡すことで、解析処理が開始されます。ファイル全体を一度に渡しても、分割して渡しても動作します。

実行結果

上記のコードを実行すると、以下のような出力が得られます。各タグやデータが検出された行番号とオフセット位置が順番に表示されていることが分かります。

Line and Offset == (1, 0)
Encountered a start tag: html
Line and Offset == (1, 6)
Encountered some data :

Line and Offset == (2, 0)
Encountered a start tag: head
Line and Offset == (2, 6)
Encountered some data :

Line and Offset == (3, 0)
Encountered a start tag: title
Line and Offset == (3, 7)
Encountered some data : welcome to Tutorials Point!
Line and Offset == (3, 34)
Encountered an end tag : title
Line and Offset == (3, 42)
Encountered some data :

Line and Offset == (4, 0)
Encountered an end tag : head
Line and Offset == (4, 7)
Encountered some data :

Line and Offset == (5, 0)
Encountered a start tag: body
Line and Offset == (5, 6)
Encountered some data :

Line and Offset == (6, 0)
Encountered a start tag: h1
Line and Offset == (6, 4)
Encountered some data : Learn anything !
Line and Offset == (6, 20)
Encountered an end tag : h1
Line and Offset == (6, 25)
Encountered some data :

Line and Offset == (7, 0)
Encountered an end tag : body
Line and Offset == (7, 7)
Encountered some data :

Line and Offset == (8, 0)
Encountered an end tag : html

このように、HTMLParserクラスを継承して必要なハンドラーメソッドをオーバーライドするだけで、用途に合わせた柔軟なHTML解析処理を簡単に実装できます。より高度なスクレイピングを行いたい場合は、BeautifulSoupなどの外部ライブラリを検討するのも良いでしょう。

  1. PythonとOpenCVで画像から直線を検出する方法|ハフ変換を徹底解説

    この記事では、「ハフ変換」と呼ばれる手法を使って、画像内の直線を検出する方法を解説します。 ハフ変換とは? ハフ変換は、数学的な形式で表現できる「単純な形状」を検出するための特徴抽出手法です。多少途切れていたり歪んでいたりしても、その形状を検出できる点が大きな特徴です。ここでは、直線の場合にどのように機能するのかを見ていきます。 ここでいう「単純」な形状とは、少数のパラメータだけで表現できる形状のことです。例えば、直線は傾きと切片の2つのパラメータだけで表現でき、円は中心座標と半径の3つのパラメータ(x, y, r)で表現できます。 ハフ変換による画像からの直線検出 直線は方程式で表現でき

  2. Pythonのpyclbrモジュールでクラス・関数情報を抽出する方法を徹底解説

    pyclbrモジュールとは Python標準ライブラリのpyclbrモジュールは、Pythonモジュール内で定義された関数・クラス・メソッドに関する情報を抽出するためのモジュールです。大きな特徴として、対象モジュールを実際にインポートするのではなく、ソースコードを直接解析して情報を取得する点が挙げられます。そのため、インポート時に副作用が発生するようなモジュールでも安全に構造を調査できます。 readmodule()関数でクラス情報を取得する pyclbrモジュールには、モジュールレベルのクラス名をキー、クラスディスクリプタを値とする辞書を返すreadmodule()関数が用意されています。