– 简单的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
/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.
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
评论被关闭。