對搜索引擎、文件索引、文檔轉換、數據檢索、站點備份或遷移等應用程序來說,經常用到對網頁(即HTML文件)的解析處理。事實上,通過Python語言提供的各種模塊,我們無需藉助Web服務器或者Web瀏覽器就能夠解析和處理HTML文檔。本文上篇中,我們介紹了一個可以幫助簡化打開位於本地和Web上的HTML文檔的Python模塊。在本文中,我們將論述如何使用Python模塊來迅速解析在HTML文件中的數據,從而處理特定的內容,如鏈接、圖像和Cookie等。同時還會介紹如何規範HTML文件的格式標籤。
一、從HTML文檔中提取鏈接
Python語言還有一個非常有用的模塊HTMLParser,該模塊使我們能夠根據HTML文檔中的標籤來簡潔、高效地解析HTML文檔。所以,在處理HTML文檔的時候,HTMLParser是最常用的模塊之一。
import urllib
class parseLinks(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
if tag == 'a':
for name,value in attrs:
if name == 'href':
print value
print self.get_starttag_text()
lParser = parseLinks()
lParser.feed(urllib.urlopen("http://www.python.org/index.html").read())
處理HTML文檔的時候,我們常常需要從其中提取出所有的鏈接。使用HTMLParser模塊後,這項任務將變得易如反掌。首先,我們需要定義一個新的HTMLParser類,以覆蓋handle_starttag()方法,我們將使用這個方法來顯示所有標籤的HRef屬性值。
定義好新的HTMLParser類之後,需要創建一個實例來返回HTMLParser對象。然後,就可以使用urllib.urlopen(url)打開HTML文檔並讀取該HTML文件的內容了。
爲了解析HTML文件的內容並顯示包含其中的鏈接,可以使用read()函數將數據傳遞給HTMLParser對象。HTMLParser對象的feed函數將接收數據,並通過定義的HTMLParser對象對數據進行相應的解析。需要注意,如果傳給HTMLParser的feed()函數的數據不完整的話,那麼不完整的標籤會保存下來,並在下一次調用feed()函數時進行解析。當HTML文件很大,需要分段發送給解析器的時候,這個功能就會有用武之地了。下面是一個具體的例子
import urllib
import sys
#定義HTML解析器
class parseLinks(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
if tag == 'a':
for name,value in attrs:
if name == 'href':
print value
print self.get_starttag_text()
#創建HTML解析器的實例
lParser = parseLinks()
#打開HTML文件
lParser.feed(urllib.urlopen( /
"http://www.python.org/index.html").read())
lParser.close()
上述代碼的運行結果太長,在此省略,您可以自己運行代碼試試。
二、從HTML文檔中提取圖像
處理HTML文檔的時候,我們常常需要從其中提取出所有的圖像。使用HTMLParser模塊後,這項任務將變得易如反掌。首先,我們需要定義一個新的HTMLParser類,以覆蓋handle_starttag()方法,該方法的作用是查找img標籤,並保存src屬性值所指的文件。
import urllib
def getImage(addr):
u = urllib.urlopen(addr)
data = u.read()
class parseImages(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
if tag == 'img':
for name,value in attrs:
if name == 'src':
getImage(urlString + "/" + value)
u = urllib.urlopen(urlString)
lParser.feed(u.read())
定義好新的HTMLParser類之後,需要創建一個實例來返回HTMLParser對象。然後,就可以使用urllib.urlopen(url)打開HTML文檔並讀取該HTML文件的內容了。
爲了解析HTML文件的內容並顯示包含其中的圖像,可以使用feed(data)函數將數據發送至HTMLParser對象。HTMLParser對象的feed函數將接收數據,並通過定義的HTMLParser對象對數據進行相應的解析。下面是一個具體的示例:
import urllib
import sys
urlString = "http://www.python.org"
#把圖像文件保存至硬盤
def getImage(addr):
u = urllib.urlopen(addr)
data = u.read()
splitPath = addr.split('/')
fName = splitPath.pop()
print "Saving %s" % fName
f = open(fName, 'wb')
f.write(data)
f.close()
#定義HTML解析器
class parseImages(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
if tag == 'img':
for name,value in attrs:
if name == 'src':
getImage(urlString + "/" + value)
#創建HTML解析器的實例
lParser = parseImages()
#打開HTML文件
u = urllib.urlopen(urlString)
print "Opening URL/n===================="
print u.info()
#把HTML文件傳給解析器
lParser.feed(u.read())
lParser.close()
上述代碼的運行結果如下所示:
====================
Date: Fri, 26 Jun 2009 10:54:49 GMT
Server: Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_wsgi/2.3 Python/2.5.2
Last-Modified: Thu, 25 Jun 2009 09:44:54 GMT
ETag: "105800d-46e7-46d29136f7180"
Accept-Ranges: bytes
Content-Length: 18151
Connection: close
Content-Type: text/html
Saving python-logo.gif
Saving trans.gif
Saving trans.gif
Saving afnic.fr.png
三、從HTML文檔中提取文本
處理HTML文檔的時候,我們常常需要從其中提取出所有的文本。使用HTMLParser模塊後,這項任務將變得非常簡單了。首先,我們需要定義一個新的HTMLParser類,以覆蓋handle_data()方法,該方法是用來解析並文本數據的。
import urllib
class parseText(HTMLParser.HTMLParser):
def handle_data(self, data):
if data != '/n':
urlText.append(data)
lParser = parseText()
lParser.feed(urllib.urlopen( /
http://docs.python.org/lib/module-HTMLParser.html).read())
定義好新的HTMLParser類之後,需要創建一個實例來返回HTMLParser對象。然後,就可以使用urllib.urlopen(url)打開HTML文檔並讀取該HTML文件的內容了。
爲了解析HTML文件的內容並顯示包含其中的文本,我們可以使用feed(data)函數將數據傳遞給HTMLParser對象。HTMLParser對象的feed函數將接收數據,並通過定義的HTMLParser對象對數據進行相應的解析。要注意的是,如果傳給HTMLParser的feed()函數的數據不完整的話,那麼不完整的標籤會保存下來,並在下一次調用feed()函數時進行解析。當HTML文件很大,需要分段發送給解析器的時候,這個功能就會有用武之地了。下面是一個具體的代碼示例:
import urllib
urlText = []
#定義HTML解析器
class parseText(HTMLParser.HTMLParser):
def handle_data(self, data):
if data != '/n':
urlText.append(data)
#創建HTML解析器的實例
lParser = parseText()
#把HTML文件傳給解析器
lParser.feed(urllib.urlopen( /
“http://docs.python.org/lib/module-HTMLParser.html” /
).read())
lParser.close()
for item in urlText:
print item
上面代碼的運行輸出過長,在此略過
四、從HTML文檔中提取Cookies
很多時候,我們都需要處理Cookie,幸運的是Python語言的cookielib模塊爲我們提供了許多自動處理在HTML中的HTTP Cookie的類。當處理要求爲客戶端設置Cookie的HTML文檔的時候,這些類對我們非常有用。
import cookielib
from urllib2 import urlopen, Request
cJar = cookielib.LWPCookieJar()
opener=urllib2.build_opener( /
urllib2.HTTPCookieProcessor(cJar))
urllib2.install_opener(opener)
r = Request(testURL)
h = urlopen(r)
for ind, cookie in enumerate(cJar):
print "%d - %s" % (ind, cookie)
cJar.save(cookieFile)
爲了從HTML文檔提取cookies,首先得使用cookielib模塊的LWPCookieJar()函數創建一個cookie jar的實例。LWPCookieJar()函數將返回一個對象,該對象可以從硬盤加載Cookie,同時還能向硬盤存放Cookie。
接下來,使用urllib2模塊的build_opener([handler, . . .])函數創建一個opener對象,當HTML文件打開時該對象將處理cookies。函數build_opener可以接收零個或多個處理程序(這些程序將按照它們被指定的順序連接在一起)作爲參數並返回一個。
注意,如果想讓urlopen()使用opener對象來打開HTML文件的話,可以調用install_opener(opener)函數,並將opener對象傳給它。否則,請使用opener對象的open(url)函數來打開HTML文件。
一旦已經創建並安裝了opener對象,就可以使用urllib2模塊中的Request(url)函數來創建一個Request對象,然後就能使用urlopen(Request)函數來打開HTML文件了。
打開HTML頁面後,該頁面的所有Cookie將被存放到LWPCookieJar對象中,之後,您可以使用LWPCookieJar對象的save(filename)函數了。
import urllib2
import cookielib
from urllib2 import urlopen, Request
cookieFile = "cookies.dat"
testURL = 'http://maps.google.com/'
#爲cookie jar 創建實例
cJar = cookielib.LWPCookieJar()
#創建HTTPCookieProcessor的opener對象
opener = urllib2.build_opener( /
urllib2.HTTPCookieProcessor(cJar))
#安裝HTTPCookieProcessor的opener
urllib2.install_opener(opener)
#創建一個Request對象
r = Request(testURL)
#打開HTML文件
h = urlopen(r)
print "頁面的頭部/n======================"
print h.info()
print "頁面的Cookies/n======================"
for ind, cookie in enumerate(cJar):
print "%d - %s" % (ind, cookie)
#保存cookies
cJar.save(cookieFile)
上述代碼的運行結果如下所示:
======================
Cache-Control: private
Content-Type: text/html; charset=ISO-8859-1
Set-Cookie: PREF=ID=5d9692b55f029733:NW=1:TM=1246015608:LM=1246015608:S=frfx--b3xt73TaEA; expires=Sun, 26-Jun-2011 11:26:48 GMT; path=/; domain=.google.com
Date: Fri, 26 Jun 2009 11:26:48 GMT
Server: mfe
Expires: Fri, 26 Jun 2009 11:26:48 GMT
Transfer-Encoding: chunked
Connection: close
頁面的Cookies
======================
0 -
五、爲HTML文檔中的屬性值添加引號
前面我們討論瞭如果根據HTML解析器中的某種處理程序來解析HTML文件,可是有時候我們卻需要使用所有的處理程序來處理HTML文檔。值得慶幸的是,使用HTMLParser模塊解析HTML文件的所有要素並不比處理鏈接或者圖像難多少。
import urllib
class parseAttrs(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
. . .
attrParser = parseAttrs()
attrParser.init_parser()
attrParser.feed(urllib.urlopen("test2.html").read())
這裏,我們將討論如何使用HTMLParser模塊來解析HTML文件,從而爲“裸奔”的屬性值加上引號。首先,我們要定義一個新的HTMLParser類,以覆蓋下面所有的處理程序來爲屬性值添加引號。
handle_charref(name)
handle_endtag(tag)
handle_entityref(ref)
handle_data(text)
handle_comment(text)
handle_pi(text)
handle_decl(text)
handle_startendtag(tag, attrs)
我們還需要在parser類中定義一個函數來初始化用於存儲解析好的數據的變量,同時還要定義另外一個函數來返回解析好的數據。
定義好新的HTMLParser類之後,需要創建一個實例來返回HTMLParser對象。使用我們創建的init函數初始化該解析器,這樣,我們就可以使用urllib.urlopen(url)打開HTML文檔並讀取該HTML文件的內容了。
爲了解析HTML文件的內容並給屬性值添加引號,可以使用feed(data)函數將數據傳遞給HTMLParser對象。HTMLParser對象的feed函數將接收數據,並通過定義的HTMLParser對象對數據進行相應的解析。下面是一個具體的示例代碼:
import urllib
import sys
#定義HTML解析器
class parseAttrs(HTMLParser.HTMLParser):
def init_parser (self):
self.pieces = []
def handle_starttag(self, tag, attrs):
fixedAttrs = ""
#for name,value in attrs:
for name, value in attrs:
fixedAttrs += "%s=/"%s/" " % (name, value)
self.pieces.append("<%s %s>" % (tag, fixedAttrs))
def handle_charref(self, name):
self.pieces.append("&#%s;" % (name))
def handle_endtag(self, tag):
self.pieces.append("" % (tag))
def handle_entityref(self, ref):
self.pieces.append("&%s" % (ref))
def handle_data(self, text):
self.pieces.append(text)
def handle_comment(self, text):
self.pieces.append("" % (text))
def handle_pi(self, text):
self.pieces.append("" % (text))
def handle_decl(self, text):
self.pieces.append("" % (text))
def parsed (self):
return "".join(self.pieces)
#創建HTML解析器的實例
attrParser = parseAttrs()
#初始化解析器數據
attrParser.init_parser()
#把HTML文件傳給解析器
attrParser.feed(urllib.urlopen("test2.html").read())
#顯示原來的文件內容
print "原來的文件/n========================"
print open("test2.html").read()
#顯示解析後的文件
print "解析後的文件/n========================"
print attrParser.parsed()
attrParser.close()
我們還需要建立一個測試文件,名爲test2.html,該文件內容可以從上述代碼的運行結果看到,具體如下所示:
========================
<html>
<head>
<meta content="text/html; charset=utf-8"
http-equiv="content-type"/>
<title>Web頁面</title>
</head>
<body>
<H1>Web頁面清單</H1>
<a href=http://www.python.org>Python網站</a>
<a href=test.html>本地頁面</a>
<img SRC=test.jpg>
</body>
</html>
解析後的文件
========================
<html>
<head >
<meta content="text/html; charset=utf-8"
http-equiv="content-type" ></meta>
<title >Web頁面</title>
</head>
<body >
<h1 >Web頁面清單</h1>
<a href="http://www.python.org" >Python網站</a>
<a href="test.html" >本地頁面</a>
<img src="test.jpg" >
</body>
</html>
六、小結
對搜索引擎、文件索引、文檔轉換、數據檢索、站點備份或遷移等應用程序來說,經常用到對網頁(即HTML文件)的解析處理。事實上,通過Python語言提供的各種模塊,我們無需藉助Web服務器或者Web瀏覽器就能夠解析和處理HTML文檔。本文將詳細介紹瞭如何使用Python模塊來迅速解析在HTML文件中的數據,從而處理特定的內容,如鏈接、圖像和Cookie等。同時,我們還給出了一個規範HTML文件的格式標籤的例子,希望本文對您會有所幫助。
作者:黃聰
出處:http://www.cnblogs.com/huangcong/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。