1. 程式人生 > >使用Python的HTMLParser解析HTML文字

使用Python的HTMLParser解析HTML文字

使用PythonHTMLParser解析HTML文字

. HTMLParser

           HTMLParserpython用來解析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>"輸出的順序.