使用Python的HTMLParser解析HTML文字
使用Python的HTMLParser解析HTML文字
一. HTMLParser
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>"和輸出的順序.