html.parser - 简单的HTML和XHTML 解析器
该模块定义了一个名为 HTMLParser的类,用于解析html和xhml格式的文本文件
class html.parser.HTMLParser(*,convert_charrefs=True)
创建一个解析器实例来解析无用的标记
convert_charrefs (该参数默认是True )为True时,所有字符引用(脚本/样式元素除外)都会自动转换为相应的Unicode字符
当遇到开始标签、结束标签,文本,注释和其他标记元素时,HTMLParser实例将调用处理方法处理HTML数据,读者应该继承HTMLParser类并重写它的方法来实现自己想要的解析方式
这个解析器不检查结束标签是否与开始标签匹配,或者通过关闭外部元素来隐式素调用结束标记处理方法
程序示例
下面是一个简单的示例,使用HTMLParser 类来输出开始标签,结束标签和数据
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.feed(data)
将一些文本数据提供给解析器。只要其由完整的元素组成就能被处理;缓存不完整的数据,直到输入更多数据或者调用close()。数据必须是str类型
HTMLParser.close()
强制处理所有的缓冲数据,就像这些数据后面有一个文件结束符一样;该方法可以由派生类重新定义,以在输入的末尾定义附加处理,但重新定义的版本应始终调用HTMLParser基类方法的close()
HTMLParser.reset()
重置实例。丢失所有未处理的数据,这在实例化时隐式调用。
HTMLParser.getpos()
返回当前行号和偏移量
HTMLParser.get_starttag_text()
返回最近打开的开始标签的文本。结构化处理通常不需要这样做,但在处理HTML“部署”或重新生成具有最小更改的输入(可以保留属性之间的空白等)时可能很有用。
遇到数据或标记元素时会调用以下方法,并且要在子类中重新他们,基类中的实现什么都不做(handle_startendtag()除外)
HTMLParser.handle_starttag(tag, attrs)
该方法处理开始标签时调用(例如 <div >)
tag参数是转换为小写的标签名称
attrs参数是(name, vaule)对的列表,包含在标签的<>内的熟悉
name被转为小写,并删除值中的引号,并且已替换字符和实体引用
例如 对于标签<A HREF="https://www.cwi.nl/"> 方法将会handle_starttag('a', [('href', 'https://www.cwi.nl/')])来处理
来着html.entities的所有实体引用都将替换为属性值
HTMLParser.handle_endtag(tag)
该方法处理结束标签 例如</div>
tag参数是转换为小写的标签名称
HTMLParser.handle_startendtag(tag, attrs)
和函数 HTMLParser.handle_starttag() 相似,但是当解析器遇到一个 XHTML格式的空标签时(<img .../>),该方法可能需要子类重写,当需要特定的词汇信息,默认实现只调用handler_starttag()和handler_endtag()
HTMLParser.handle_data(data)
调用该方法来处理任意数据(文本节点和<script>...</script>
和 <style>...</style>中的内容
)
HTMLParser.handle_entityref(name)
调用此方法来处理表单和名称的命名字符引用;(>)其中name是一般实体引用()如果convert_charrefs为True 该方法永远不会被调用
HTMLParser.handle_charref(name)
调用此方法来处理形式为&#NNN的十进制和十六进制数字字符引用&#xNNN.例如,&gt;的十进制等效值是>,而十六进制是>在这种情况下,该方法将接收'62'或'x3E'。
HTMLParser.handle_comment(data)
遇到注释时会调用此方法(<!--comment-->)
例如,注释<!—-comment-—>将导致使用参数'comment'调用此方法
Internet Explorer条件注释(condcoms)的内容也将发送到此方法,因此,对于<! - [if IE 9]> IE9特定内容<![endif] - >,此方法将收到'[如果IE 9]> IE9特定内容<![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.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
脚本和样式元素的内容按原样返回,无需进一步解析
>>> 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]
解析命名和数字字符引用并将它们转换为正确的char(注意:这3个引用都等同于'>')
>>> parser.feed('>>>') Named ent: > Num ent : > Num ent : >
将不完整的块提供给feed()可以工作,但handle_data()可能会被多次调用:
>>> 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
- 上一篇 »CSS 学习笔记
- 下一篇 »HTML中放置CSS的三种方式和CSS选择器