使用Python中的HTMLParser、cookielib抓取和解析網頁、從HTML文檔中提取鏈接、圖像、文本、Cookies(二)

  對搜索引擎、文件索引、文檔轉換、數據檢索、站點備份或遷移等應用程序來說,經常用到對網頁(即HTML文件)的解析處理。事實上,通過Python語言提供的各種模塊,我們無需藉助Web服務器或者Web瀏覽器就能夠解析和處理HTML文檔。本文上篇中,我們介紹了一個可以幫助簡化打開位於本地和Web上的HTML文檔的Python模塊。在本文中,我們將論述如何使用Python模塊來迅速解析在HTML文件中的數據,從而處理特定的內容,如鏈接、圖像和Cookie等。同時還會介紹如何規範HTML文件的格式標籤。

  一、從HTML文檔中提取鏈接

  Python語言還有一個非常有用的模塊HTMLParser,該模塊使我們能夠根據HTML文檔中的標籤來簡潔、高效地解析HTML文檔。所以,在處理HTML文檔的時候,HTMLParser是最常用的模塊之一。

  import 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 HTMLParser

  
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 HTMLParser

  
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 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()

  上述代碼的運行結果如下所示:

  Opening URL

  
====================

  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 HTMLParser

  
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 HTMLParser

  
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 urllib2

  
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 os

  
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 HTMLParser

  
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_starttag(tag, attrs)

  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 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文件的格式標籤的例子,希望本文對您會有所幫助。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章