使用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函数, 你想干嘛都可以.
三. 举例
3.1 该例子分析HTML文本, 并写入文件
#!/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/