很早之前,在.net平台下写过一个分析html代码的程序,那时候的思想是将html代码解析成一棵类似树的结构,然后在分析其中的标签。Python中,HTTPParser模块,更像是在过程中进行解析,模拟遇到开始标签怎样开始,怎样处理属性和值,又当遇到结束标签该怎样结束等等过程。对于格式规范、代码简洁的html容易解析,如果复杂、不规范的html解析会很繁琐。
HTTPParser:
HTMLParser是python用来解析html的模块。它可以分析出html里面的标签、数据等等,是一种处理html的简便途径。
HTMLParser采用的是一种事件驱动的模式,当HTMLParser找到一个特定的标记时,它会去调用一个用户定义的函数,以此来通知程序处理。
它主要的用户回调函数的命名都是以handler_开头的,都是HTMLParser的成员函数。
当我们使用时,就从HTMLParser派生出新的类,然后重新定义这几个以handler_开头的函数即可。
例子:
写了小例子,用于分析获取到我们东南大学教务处网站的信息公告栏,内容比较简单。
打开jwc网站。
查看源代码,可以发现信息公告栏里有这样格式的html片段:
<td width="314" height="20"><a href="/admin/disp.asp?id=5323" target="newwin">关于申请2012年德国乌尔姆大学本科交流项目的报...</a><img src="imagess/new.gif" width="26" height="10"></td>
<td width="76" height="20">2012-1-9</td>
于是,可以简单的提取包含href="/admin/disp.asp?"属性的<a>标签获取文本和链接,以及紧接着的<td>标签获取日期值。
具体python实现代码如下:
#-*- encoding:gb2312 -*-
'''
Created on 2012-1-9
@author: xiaojay
'''
from HTMLParser import HTMLParser
from htmlentitydefs import entitydefs
import urllib2
url = "http://jwc.seu.edu.cn"
class NewsParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.link = ""
self.text = ""
self.items = [] #保存提取结果
self.flag = False
self.parse_date = False
self.date_start = False
def handle_starttag(self,tag,attrs):
#处理开始标签
if tag=='a' and attrs:
for key ,value in attrs:
if key=='href':
index = value.find("?")
if index>0 and value[0:index]=="/admin/disp.asp":
self.flag = True
self.parse_date = True
self.link = value
if tag == "td" and self.parse_date == True :
self.date_start = True
def handle_data(self,data):
#处理数据
if self.flag == True :
self.text = data
if self.date_start == True :
self.items.append((self.text,self.link,data))
def handle_entityref(self , name):
#处理实体引用
if entitydefs.has_key(name):
self.handle_data(name)
else :
self.handle_data("&"+name )
def handle_endtag(self,tag):
#处理结束标签
if tag == 'a' and self.flag== True :
self.flag = False
if tag == 'td' and self.parse_date and self.date_start :
self.parse_date = False
self.date_start = False
def getItems(self):
return self.items
req = urllib2.Request(url)
fd = urllib2.urlopen(req)
newsparser = NewsParser()
#调用feed方法,开始处理
newsparser.feed(fd.read())
items = newsparser.getItems()
for text , link , date in items :
print text , link , date
运行结果:
关于申请2012年德国乌尔姆大学本科交流项目的报... /admin/disp.asp?id=5323 2012-1-9
关于公布“东南大学第五届PLD设计竞赛”结果的通知 /admin/disp.asp?id=5322 2012-1-6
关于公布“2011年国家大学生创新性实验计划项目... /admin/disp.asp?id=5321 2012-1-6
关于公布2011年“国家大学生创新性实验计划项目... /admin/disp.asp?id=5320 2012-1-6
关于申请暑假东南大学与台湾中原大学交换生的报名通知 /admin/disp.asp?id=5319 2012-1-5
本科生申报2012年SRTP项目的预通知 /admin/disp.asp?id=5318 2012-1-5
关于申请2012年法国巴黎电子信息学院本科交流项... /admin/disp.asp?id=5317 2012-1-5
关于申请2012年日本北海道大学本科交流项目的报... /admin/disp.asp?id=5316 2012-1-4