html.parser —単純なHTMLおよびXHTMLパーサー—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/library/html.parser
移動先:案内検索

html.parser —単純なHTMLおよびXHTMLパーサー

ソースコード: :source: `Lib / html / parser.py`



このモジュールは、HTML(ハイパーテキストマークアップ言語)およびXHTMLでフォーマットされたテキストファイルを解析するための基礎として機能するクラス HTMLParser を定義します。

class html.parser.HTMLParser(*, convert_charrefs=True)

無効なマークアップを解析できるパーサーインスタンスを作成します。

convert_charrefsTrue(デフォルト)の場合、すべての文字参照(script / style要素の参照を除く)は、対応するUnicodeに自動的に変換されます。文字。

HTMLParser インスタンスにはHTMLデータが供給され、開始タグ、終了タグ、テキスト、コメント、およびその他のマークアップ要素が検出されると、ハンドラーメソッドが呼び出されます。 ユーザーは、 HTMLParser をサブクラス化し、そのメソッドをオーバーライドして、目的の動作を実装する必要があります。

このパーサーは、終了タグが開始タグと一致することを確認したり、外部要素を閉じることによって暗黙的に閉じられた要素の終了タグハンドラーを呼び出したりしません。

バージョン3.4で変更: convert_charrefs キーワード引数が追加されました。

バージョン3.5で変更:引数 convert_charrefs のデフォルト値はTrueになりました。

HTMLパーサーアプリケーションの例

基本的な例として、以下は、 HTMLParser クラスを使用して、開始タグ、終了タグ、およびデータが検出されたときにそれらを出力する単純なHTMLパーサーです。

from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        print("Encountered a start tag:", tag)

    def handle_endtag(self, tag):
        print("Encountered an end tag :", tag)

    def handle_data(self, data):
        print("Encountered some data  :", data)

parser = MyHTMLParser()
parser.feed('<html><head><title>Test</title></head>'
            '<body><h1>Parse me!</h1></body></html>')

出力は次のようになります。

Encountered a start tag: html
Encountered a start tag: head
Encountered a start tag: title
Encountered some data  : Test
Encountered an end tag : title
Encountered an end tag : head
Encountered a start tag: body
Encountered a start tag: h1
Encountered some data  : Parse me!
Encountered an end tag : h1
Encountered an end tag : body
Encountered an end tag : html

HTMLParser メソッド

HTMLParser インスタンスには次のメソッドがあります。

HTMLParser.feed(data)
パーサーにテキストをフィードします。 完全な要素で構成されている限り、処理されます。 不完全なデータは、さらにデータが供給されるか、 close()が呼び出されるまでバッファリングされます。 datastr である必要があります。
HTMLParser.close()
バッファリングされたすべてのデータを、ファイルの終わりマークが後に続くかのように強制的に処理します。 このメソッドは、入力の最後に追加の処理を定義するために派生クラスによって再定義できますが、再定義されたバージョンは常に HTMLParser 基本クラスメソッド close()を呼び出す必要があります。
HTMLParser.reset()
インスタンスをリセットします。 未処理のデータをすべて失います。 これは、インスタンス化時に暗黙的に呼び出されます。
HTMLParser.getpos()
現在の行番号とオフセットを返します。
HTMLParser.get_starttag_text()
最後に開いた開始タグのテキストを返します。 これは通常、構造化処理には必要ありませんが、「デプロイされたまま」のHTMLを処理したり、最小限の変更で入力を再生成したりする場合に役立ちます(属性間の空白を保持できるなど)。

次のメソッドは、データまたはマークアップ要素が検出されたときに呼び出され、サブクラスでオーバーライドされることを目的としています。 基本クラスの実装は何もしません( handle_startendtag()を除く):

HTMLParser.handle_starttag(tag, attrs)

このメソッドは、タグの開始を処理するために呼び出されます(例: <div id="main">)。

tag 引数は、小文字に変換されたタグの名前です。 attrs 引数は、タグの<>ブラケット内にある属性を含む(name, value)ペアのリストです。 name は小文字に変換され、 value の引用符は削除され、文字とエンティティの参照は置き換えられました。

たとえば、タグ<A HREF="https://www.cwi.nl/%22>の場合、このメソッドはhandle_starttag('a', [('href', 'https://www.cwi.nl/')])として呼び出されます。

html.entities からのすべてのエンティティ参照は、属性値で置き換えられます。

HTMLParser.handle_endtag(tag)

このメソッドは、要素の終了タグを処理するために呼び出されます(例: </div>)。

tag 引数は、小文字に変換されたタグの名前です。

HTMLParser.handle_startendtag(tag, attrs)
handle_starttag()に似ていますが、パーサーがXHTMLスタイルの空のタグ(<img ... />)を検出したときに呼び出されます。 このメソッドは、この特定の字句情報を必要とするサブクラスによってオーバーライドされる場合があります。 デフォルトの実装では、 handle_starttag()および handle_endtag()を呼び出すだけです。
HTMLParser.handle_data(data)
このメソッドは、任意のデータを処理するために呼び出されます(例: テキストノードと<script>...</script>および<style>...</style>のコンテンツ)。
HTMLParser.handle_entityref(name)
このメソッドは、&name;の形式の名前付き文字参照を処理するために呼び出されます(例: &gt;)、ここで name は一般的なエンティティ参照です(例: 'gt')。 convert_charrefsTrueの場合、このメソッドは呼び出されません。
HTMLParser.handle_charref(name)
このメソッドは、&#NNN;および&#xNNN;の形式の10進数および16進数の数字参照を処理するために呼び出されます。 たとえば、&gt;に相当する10進数は&#62;ですが、16進数は&#x3E;です。 この場合、メソッドは'62'または'x3E'を受け取ります。 convert_charrefsTrueの場合、このメソッドは呼び出されません。
HTMLParser.handle_comment(data)

このメソッドは、コメントが検出されたときに呼び出されます(例: <!--comment-->)。

たとえば、コメント<!-- comment -->を指定すると、このメソッドは引数' comment 'で呼び出されます。

Internet Explorerの条件付きコメント(condcom)のコンテンツもこのメソッドに送信されるため、<!--[if IE 9]>IE9-specific content<![endif]-->の場合、このメソッドは'[if IE 9]>IE9-specific content<![endif]'を受信します。

HTMLParser.handle_decl(decl)

このメソッドは、HTMLのDoctype宣言を処理するために呼び出されます(例: <!DOCTYPE html>)。

decl パラメーターは、<!...>マークアップ内の宣言の内容全体になります(例: 'DOCTYPE html')。

HTMLParser.handle_pi(data)

処理命令が検出されたときに呼び出されるメソッド。 data パラメーターには、処理命令全体が含まれます。 たとえば、処理命令<?proc color='red'>の場合、このメソッドはhandle_pi("proc color='red'")と呼ばれます。 これは、派生クラスによってオーバーライドされることを目的としています。 基本クラスの実装は何もしません。

ノート

HTMLParser クラスは、命令の処理にSGML構文規則を使用します。 末尾の'?'を使用したXHTML処理命令により、'?'データに含まれます。

HTMLParser.unknown_decl(data)

このメソッドは、認識されない宣言がパーサーによって読み取られたときに呼び出されます。

data パラメーターは、<![...]>マークアップ内の宣言の内容全体になります。 派生クラスによってオーバーライドされると便利な場合があります。 基本クラスの実装は何もしません。


次のクラスは、より多くの例を説明するために使用されるパーサーを実装します。

from html.parser import HTMLParser
from html.entities import name2codepoint

class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        print("Start tag:", tag)
        for attr in attrs:
            print("     attr:", attr)

    def handle_endtag(self, tag):
        print("End tag  :", tag)

    def handle_data(self, data):
        print("Data     :", data)

    def handle_comment(self, data):
        print("Comment  :", data)

    def handle_entityref(self, name):
        c = chr(name2codepoint[name])
        print("Named ent:", c)

    def handle_charref(self, name):
        if name.startswith('x'):
            c = chr(int(name[1:], 16))
        else:
            c = chr(int(name))
        print("Num ent  :", c)

    def handle_decl(self, data):
        print("Decl     :", data)

parser = MyHTMLParser()

Doctypeの解析:

>>> parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
...             '"http://www.w3.org/TR/html4/strict.dtd">')
Decl     : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"

いくつかの属性とタイトルを持つ要素の解析:

>>> parser.feed('<img src="python-logo.png" alt="The Python logo">')
Start tag: img
     attr: ('src', 'python-logo.png')
     attr: ('alt', 'The Python logo')
>>>
>>> parser.feed('<h1>Python</h1>')
Start tag: h1
Data     : Python
End tag  : h1

scriptおよびstyle要素の内容は、さらに解析せずにそのまま返されます。

>>> parser.feed('<style type="text/css">#python { color: green }</style>')
Start tag: style
     attr: ('type', 'text/css')
Data     : #python { color: green }
End tag  : style

>>> parser.feed('<script type="text/javascript">'
...             'alert("<strong>hello!</strong>");</script>')
Start tag: script
     attr: ('type', 'text/javascript')
Data     : alert("<strong>hello!</strong>");
End tag  : script

コメントの解析:

>>> parser.feed('<!-- a comment -->'
...             '<!--[if IE 9]>IE-specific content<![endif]-->')
Comment  :  a comment
Comment  : [if IE 9]>IE-specific content<![endif]

名前付き文字参照と数字参照を解析し、それらを正しい文字に変換します(注:これらの3つの参照はすべて'>'と同等です):

>>> parser.feed('&gt;&#62;&#x3E;')
Named ent: >
Num ent  : >
Num ent  : >

不完全なチャンクの feed()へのフィードは機能しますが、 handle_data()が複数回呼び出される場合があります( convert_charrefsTrueに設定されている場合を除く) :

>>> for chunk in ['<sp', 'an>buff', 'ered ', 'text</s', 'pan>']:
...     parser.feed(chunk)
...
Start tag: span
Data     : buff
Data     : ered
Data     : text
End tag  : span

無効なHTMLの解析(例: 引用符で囲まれていない属性)も機能します:

>>> parser.feed('<p><a class=link href=#main>tag soup</p ></a>')
Start tag: p
Start tag: a
     attr: ('class', 'link')
     attr: ('href', '#main')
Data     : tag soup
End tag  : p
End tag  : a