You are here:  Home » Python » – 简单的HTML和XHTML解析器 – 结构化标记处理工具(Python教程)(参考资料)

html.parser– 简单的HTML和XHTML解析器

源代码: Lib / html / parser.py


这个模块定义了一个以HTMLParser为基础的类forparsing用HTML格式的文本文件(超文本标记语言)和XHTML。

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

创建一个能解析无效标记的解析器实例.

如果convert_charrefsTrue(默认值),所有字符引用(除了script/style elements中的那些)区域自动转换为相应的Unicode字符.

HTMLParser实例输入HTML数据,并在启动标记,结束标记,文本,注释和其他标记元素时调用处理程序方法。用户应该子类化HTMLParser并覆盖其方法以实现所需的行为.

此解析器不会检查结束标记是否与开始标记匹配,或者是否通过关闭隐式关闭的元素调用end-taghandler一个外部元素

更改版本3.4:convert_charrefs关键字参数添加.

更改版本3.5:参数的默认值convert_charrefs现在是True.

示例HTML解析器应用程序

作为一个基本示例,下面是一个简单的HTML解析器,它使用HTMLParser类打印出开始标记,结束标记和数据他们遇到:

from html.parser import HTMLParserclass 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: htmlEncountered a start tag: headEncountered a start tag: titleEncountered some data  : TestEncountered an end tag : titleEncountered an end tag : headEncountered a start tag: bodyEncountered a start tag: h1Encountered some data  : Parse me!Encountered an end tag : h1Encountered an end tag : bodyEncountered an end tag : html

HTMLParser方法

HTMLParser实例有以下方法:

HTMLParser.feeddata

将一些文本提供给解析器。只要它由完整的元素组成,它就被处理;不完整的数据被缓冲,直到输入更多数据或调用close()data必须是str.

HTMLParser.close

强制处理所有缓冲数据,就好像它后面跟着文件结束一样。此方法可以由派生类重新定义,以在输入结束时定义附加处理,但重新定义的版本应始终调用HTMLParser基类方法close().

HTMLParser.reset

重置实例。丢失所有未处理的数据。这在实例时隐含地称为

HTMLParser.getpos)

返回当前行号和偏移量

HTMLParser.get_starttag_text// ( )

返回最近打开的开始标记的文本。结构化处理通常不需要这样做,但在处理HTML“asdeployed”或重新生成具有最小更改的输入(可以保留属性之间的空白等)时可能很有用.

遇到数据或标记元素时会调用以下方法,并且它们要在子类中重写。基类实现什么都不做(除了handle_startendtag()):

HTMLParser.handle_starttagtag, attrs

调用此方法来处理标记的开始(例如<div id="main">).

tag参数是转换为标记的标记的名称小写。attrs参数是(name, value)包含在标签的内容中找到的属性的对<>括号。name将被翻译成小写,并在中引用value已被删除,字符和实体引用已被替换.

例如,对于标签<A HREF="https://www.cwi.nl/">,这个方法可以称为handle_starttag("a", [("href", "https://www.cwi.nl/")]).

来自的所有实体引用html.entities在attributevalues中被替换.

HTMLParser.handle_endtagtag

调用此方法来处理元素的结束标记(例如</div>).

tag参数是转换为小写的标签的名称.

HTMLParser.handle_startendtagtag, attrs

handle_starttag()类似,但是当解析器遇到一个XHTML样式时调用空标签(<img ... />)。这个方法可能被需要这个特定词汇信息的子类所覆盖;defaultimplementation简单地调用handle_starttag()handle_endtag().

HTMLParser.handle_datadata

调用此方法来处理任意数据(例如文本节点和<script>...</script><style>...</style>的内容.

HTMLParser.handle_entityref (name

调用此方法来处理表单&name;(例如&gt;),其中name是一般实体引用(例如"gt")。如果convert_charrefsTrue.

HTMLParser.handle_charrefname

调用此方法来处理&#NNN;&#xNNN;形式的十进制和十六进制数字字符引用。例如,&gt;的十次等价是&#62;,而十六进制是&#x3E;;在这种情况下,方法将接收"62""x3E"。如果convert_charrefsTrue.

HTMLParser.handle_commentdata

在遇到注释时调用此方法(例如<!--comment-->),则不会调用此方法.

例如,注释<!-- comment -->会导致这个方法与参数" comment ".

一起使用Internet Explorer条件注释(condcoms)的内容也会同意这个方法,所以,对于<!--[if IE 9]>IE9-specific content<![endif]-->,这个方法会收到"[if IE 9]>IE9-specific content<![endif]".

HTMLParser.handle_decldecl

这个方法被调用来处理一个HTML doctype声明(例如<!DOCTYPE html>).

decl参数将是<!...>标记内的声明的全部内容(例如"DOCTYPE html").

HTMLParser.handle_pidata

遇到处理指令时调用的方法。data参数将包含整个处理指令。例如,对于处理指令<?proc color="red">,此方法将被称为handle_pi("proc color="red"")。它旨在被派生类覆盖;基类实现什么都不做.

注意

HTMLParser类使用SGML语法规则来处理指令。使用尾随"?"的XHTML处理指令将"?"包含在data.

HTMLParser.unknown_decldata

这个方法被调用时解析器读取一个无法识别的声明.

data参数将是<![...]>标记内声明的全部内容。有时被被剥夺的阶级所覆盖是有用的。基类实现什么都不做.

示例

下面的类实现了一个解析器,用于说明更多示例:

from html.parser import HTMLParserfrom html.entities import name2codepointclass 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: h1Data     : PythonEnd tag  : h1

scriptstyle元素的内容按原样返回,无需进一步解析:

>>> 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 commentComment  : [if IE 9]>IE-specific content<![endif]

解析命名和数字字符引用并将它们转换为正确的字符(注意:这3个引用都等于">"):

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

将不完整的块提供给feed()有效,但handle_data()可能被多次调用(除非convert_charrefs设置为True):

>>> for chunk in ["<sp", "an>buff", "ered ", "text</s", "pan>"]:...     parser.feed(chunk)...Start tag: spanData     : buffData     : eredData     : textEnd tag  : span

解析无效的HTML(例如,未引用的属性)也有效:

>>> parser.feed("<p><a class=link href=#main>tag soup</p ></a>")Start tag: pStart tag: a     attr: ("class", "link")     attr: ("href", "#main")Data     : tag soupEnd tag  : pEnd tag  : a

评论被关闭。