抓取网页内容

对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来讲,常常用到对网页(即HTML文件)的解析处理。事实上,经过Python语言 提供的各类模块,咱们无需借助Web服务器或者Web浏览器就可以解析和处理HTML文档。本文上篇中,咱们介绍了一个能够帮助简化打开位于本地和Web 上的HTML文档的Python模块。在本文中,咱们将论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如连接、图 像和Cookie等。同时还会介绍如何规范HTML文件的格式标签。

1、从HTML文档中提取连接html

Python语言还有一个很是有用的模块HTMLParser,该模块使咱们可以根据HTML文档中的标签来简洁、高效地解析HTML文档。因此,在处理HTML文档的时候,HTMLParser是最经常使用的模块之一。python

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文件很大,须要分段发送给解析器的时候,这个功能就会 有用武之地了。下面是一个具体的例子cookie

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

2、从HTML文档中提取图像 dom

处理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 0 9 : 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


3、从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

4、从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


5、为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 >
相关文章
相关标签/搜索