– 简单的HTML和XHTML解析器 – 结构化标记处理工具(Python教程)(参考资料)
html.parser– 简单的HTML和XHTML解析器
源代码: Lib / html / parser.py
这个模块定义了一个以HTMLParser为基础的类forparsing用HTML格式的文本文件(超文本标记语言)和XHTML。
- class
html.parser.HTMLParser(*, convert_charrefs=True) -
如果convert_charrefs是
True(默认值),所有字符引用(除了script/styleelements中的那些)区域自动转换为相应的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.feed(data)-
将一些文本提供给解析器。只要它由完整的元素组成,它就被处理;不完整的数据被缓冲,直到输入更多数据或调用
close()。data必须是str.
HTMLParser.close()-
强制处理所有缓冲数据,就好像它后面跟着文件结束一样。此方法可以由派生类重新定义,以在输入结束时定义附加处理,但重新定义的版本应始终调用
HTMLParser基类方法close().
HTMLParser.reset()-
重置实例。丢失所有未处理的数据。这在实例时隐含地称为
HTMLParser.getpos()-
返回当前行号和偏移量
HTMLParser.get_starttag_text// ( )-
返回最近打开的开始标记的文本。结构化处理通常不需要这样做,但在处理HTML“asdeployed”或重新生成具有最小更改的输入(可以保留属性之间的空白等)时可能很有用.
遇到数据或标记元素时会调用以下方法,并且它们要在子类中重写。基类实现什么都不做(除了handle_startendtag()):
HTMLParser.handle_starttag(tag, attrs)-
调用此方法来处理标记的开始(例如
<div id="main">).tag参数是转换为标记的标记的名称小写。attrs参数是
(name, value)包含在标签的内容中找到的属性的对<>括号。name将被翻译成小写,并在中引用value已被删除,字符和实体引用已被替换.例如,对于标签
<A HREF="https://www.cwi.nl/">,这个方法可以称为handle_starttag("a", [("href", "https://www.cwi.nl/")]).
HTMLParser.handle_endtag(tag)-
调用此方法来处理元素的结束标记(例如
</div>).tag参数是转换为小写的标签的名称.
HTMLParser.handle_startendtag(tag, attrs)-
与
handle_starttag()类似,但是当解析器遇到一个XHTML样式时调用空标签(<img ... />)。这个方法可能被需要这个特定词汇信息的子类所覆盖;defaultimplementation简单地调用handle_starttag()和handle_endtag().
HTMLParser.handle_entityref(name)-
调用此方法来处理表单
&name;(例如>),其中name是一般实体引用(例如"gt")。如果convert_charrefs是True.
HTMLParser.handle_charref(name)-
调用此方法来处理
&#NNN;和&#xNNN;形式的十进制和十六进制数字字符引用。例如,>的十次等价是>,而十六进制是>;在这种情况下,方法将接收"62"或"x3E"。如果convert_charrefs是True.
HTMLParser.handle_comment(data)-
在遇到注释时调用此方法(例如
<!--comment-->),则不会调用此方法.例如,注释
<!-- comment -->会导致这个方法与参数" comment ".一起使用Internet Explorer条件注释(condcoms)的内容也会同意这个方法,所以,对于
<!--[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处理指令将"?"包含在data.
HTMLParser.unknown_decl(data)-
这个方法被调用时解析器读取一个无法识别的声明.
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
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 commentComment : [if IE 9]>IE-specific content<![endif]
解析命名和数字字符引用并将它们转换为正确的字符(注意:这3个引用都等于">"):
>>> parser.feed(">>>")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
评论被关闭。