使用Python的HTMLParser解析HTML文本
HTMLParser是python用来解析html的模块。它可以分析出html里面的标签、数据等等,是一种处理html的简便途径。 HTMLParser采用的是一种事件驱动的模式, 当HTMLParser找到一个特定的标记时, 它会去调用一个用户定义的函数(就是回调函数).
它主要的用户回调函数的命名都是以handler_开头的, 都是HTMLParser的成员函数. 当我们使用时,就从HTMLParser派生出新的类, 然 后重新定义这几个以handler_开头的函数即可.
这几个函数包括:
handle_startendtag 处理开始标签和结束标签, 例如 <img src='http://www.baidu.com/logo.gif'/>
handle_starttag 处理开始标签, 比如<body>
handle_endtag 处理结束标签, 比如</body>
handle_charref 处理特殊字符串, 就是以&#开头的, 一般是内码表示的字符
handle_entityref 处理一些特殊字符, 以&开头的, 比如
handle_data 处理数据, 就是<xx>data</xx>中间的那些数据
handle_comment 处理注释
handle_decl 处理<!开头的, 比如<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
handle_pi 处理形如<?instruction>的东西
import HTMLParser # 重写的这些类函数相当于回调函数, 在不同的情况会调用不同的类函数. class MyClass(HTMLParser.HTMLParser): def __init__(self): ''' 构造函数, 做一些初始化工作 ''' HTMLParser.__init__(self) def handle_starttag(self, tag, attrs): ''' tag 表示解析到的任何标签 attrs是一个序列, 序列中的内容为元组, 一个元组中有两个元素, 分别是该标签的属性和该属性的值判断逻辑语句 ''' def handle_data(self,data): ''' 这里的data为上面tag标签包含的内容 ''' def handle_endtag(self,tag): ''' 这里tag对应的上面那个标签的结束标签 例如上的标签为<p>,则这里对应的是</p> ''' def getresult(self): ''' 写一些自己要返回的内容 ''' if __name__=="__main__": obname = MyClass() obname.feed(html_data) # 这里传入HTML文本. obname.getresult()
在obname.feed(html_data)被调用后, HTMLParser解析HTML文本.
例如
遇到标签开始, 就会调用handle_starttag函数了, 你根据标签做自己想做的事情, 例如输出显示, 其他等.
遇到内容, 就会调用handle_data函数, 你想干嘛都可以.
#!/usr/bin/env python # Python 2.7.3 # 使用HTMLParser解析HTML文本, 把分析结果写入文件 htmldata.txt import urllib2 import HTMLParser # from HTMLParser import HTMLParser class MyParser(HTMLParser.HTMLParser): def __init__(self): HTMLParser.HTMLParser.__init__(self) # 调用父类的构造函数, 这里调用时有self的 self.f = open('htmldata.txt', 'w') # 写入文件(你使用浏览器打开这个文件看看) def __del__(self): self.f.close() #HTMLParser.HTMLParser.__del__(self) def handle_starttag(self, tag, attrs): print >> self.f, "Start tag:", tag for attr in attrs: print >> self.f, " attr:", attr def handle_endtag(self, tag): print >> self.f, "End tag :", tag def handle_data(self, data): print >> self.f, "Data :", data def handle_comment(self, data): print >> self.f, "Comment :", data #def handle_entityref(self, name): # c = unichr(name2codepoint[name]) # print >> self.f, "Named ent:", c def handle_charref(self, name): if name.startswith('x'): c = unichr(int(name[1:], 16)) else: c = unichr(int(name)) print >> self.f, "Num ent :", c def handle_decl(self, data): print >> self.f, "Decl :", data if __name__ == '__main__': req = urllib2.Request('http://www.baidu.com') response = urllib2.urlopen(req) htmlStr = response.read() # 得到百度的HTML文本 my = MyParser() # 传入要分析的数据,是html的。 htmlStr = '<html><head><title>Test</title></head><body><h1>Parse me!</h1></body></html>' my.feed(htmlStr)
输出结果:
Start tag: html
Start tag: head
Start tag: title
Data : Test
End tag : title
End tag : head
Start tag: body
Start tag: h1
Data : Parse me!
End tag : h1
End tag : body
End tag : html
对比一些要分析的HTML文本"<html><head><title>Test</title></head><body><h1>Parse me!</h1></body></html>"和输出的顺序.
参考: http://cloudaice.com/yong-pythonde-htmlparserfen-xi-htmlye-mian/