urllib.parse在python2.7中怎么用

Python010

urllib.parse在python2.7中怎么用,第1张

最新版的python3.3.0已经发布了。相较于python3.0,3.2的改动并不大。但网上的大量的教程等大都以2.x版本为基础。这为想要从python3.0学起的菜鸟带来了不少的困难。 作为一只菜鸟,最近想学习一下python中urllib模块的使用方法。从网上找的最简单的实例:把google 首页的html抓取下来并显示在控制台上 代码:

[python] view plain copy

import    urllib

print    urllib.urlopen('http://www.google.com').read()

首先,使用过python3.0的朋友都知道,print已经变成含树了,需要括号。但这不是主要问题。问题是控制台显示错误,说urllib模块中没有urlopen方法。 奇怪了,网上的教程能错了?又尝试help(urllib),发现什么方法都没有,只提供了package contents,里面有5个名字。 

[python] view plain copy

import urllib

help(urllib)

3.0版本中已经将urllib2、urlparse、和robotparser并入了urllib中,并且修改urllib模块,其中包含5个子模块,即是help()中看到的那五个名字。

为了今后使用方便,在此将每个包中包含的方法列举如下:

urllib.error: ContentTooShortErrorHTTPErrorURLError

urllib.parse: parseqsparseqslquotequotefrombytesquote_plusunquote unquoteplusunquoteto_bytesurldefragurlencodeurljoin urlparseurlspliturlunparseurlunsplit

urllib.request: AbstractBasicAuthHandlerAbstractDigestAuthHandlerBaseHandlerCatheFTPHandlerFTPHandlerFancyURLopenerFileHandlerHTTPBasicAuthHandlerHTTPCookieProcessorHTTPDefaultErrorHandlerHTTPDigestAuthHandlerHTTPErrorProcessorlHTTPHandlerHTTPPasswordMgrHTTPPasswordMgrWithDefaultRealmHTTPRedirectHandlerHTTPSHandlerOpenerDirectorProxyBasicAuthHandler ProxyDigestAuthHandlerProxyHandlerRequestURLopenerUnknowHandlerbuildopenergetproxiesinstallopenerpathname2urlurl2pathnameurlcleanupurlopenurlretrieve

urllib.response: addbaseaddclosehookaddinfoaddinfourl

urllib.robotparser: RobotFileParser

---------------------------------------------------------------------------------------------------------

在2.X版本下,打开HTML文档的实例:

[python] view plain copy

import urllib

webURL = "http://www.python.org"

localURL = "index.html"

#通过URL打开远程页面

u = urllib.urlopen(webURL)

buffer = u.read()

print u.info()

print "从%s读取了%d 字节数据. " % (u.geturl(),len(buffer) )

#通过URL打开本地页面

u = urllib.urlopen(localURL)

buffer = u.read()

print u.info()

print "从%s读取了%d 字节数据. " % (u.geturl(),len(buffer) )

运行结果如下:

[html] view plain copy

Date: Fri, 26 Jun 2009 10:22:11 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

从http://www.python.org读取了18151 字节数据.

Content-Type: text/html

Content-Length: 865

Last-modified: Fri, 26 Jun 2009 10:16:10 GMT

从index.html读取了865 字节数据.

若要通过urllib模块中的urlopen(url [,data])函数打开一个HTML文档,必须提供该文档的URL地址,包括文件名。函数urlopen不仅可以打开位于远程web服务器上的文件,而 且可以打开一个本地文件,并返回一个类似文件的对象,我们可以通过该对象从HTML文档中读出数据。

一旦打开了HTML文档,我们就可以像使用常规文件一样使用read([nbytes])、readline()和readlines()函数来对文件进行读操作。若要读取整个HTML文档的内容的话,您可以使用read()函数,该函数将文件内容作为字符串返回。

打开一个地址之后,您可以使用geturl()函数取得被获取网页的真正的URL。这是很有用的,因为urlopen(或使用的opener对象)也许会伴随一个重定向。获取的网页URL也许和要求的网页URL不一样。

另一个常用的函数是位于从urlopen返回的类文件对象中的info()函数,这个函数可以返回URL位置有关的元数据,比如内容长度、内容类型,等等。下面通过一个较为详细的例子来对这些函数进行说明。

--------------------------------------------------------------------------------------------------------------------------

在2.X版本下,urlparse使用实例:

[python] view plain copy

import urlparse

URLscheme = "http"

URLlocation = "www.python.org"

URLpath = "lib/module-urlparse.html"

modList = ("urllib", "urllib2", \

"httplib", "cgilib")

#将地址解析成组件

print "用Google搜索python时地址栏中URL的解析结果"

parsedTuple = urlparse.urlparse(

"http://www.google.com/search?

hl=en&q=python&btnG=Google+Search")

print parsedTuple

#将组件反解析成URL

print "\反解析python文档页面的URL"

unparsedURL = urlparse.urlunparse( \

(URLscheme, URLlocation, URLpath, '', '', ''))

print "\t" + unparsedURL

#将路径和新文件组成一个新的URL

print " 利用拼接方式添加更多python文档页面的URL"

for mod in modList:

newURL = urlparse.urljoin(unparsedURL, \

"module-%s.html" % (mod))

print "\t" + newURL

#通过为路径添加一个子路径来组成一个新的URL

print " 通过拼接子路径来生成Python文档页面的URL"

newURL = urlparse.urljoin(unparsedURL,

"module-urllib2/request-objects.html")

print "\t" + newURL

运行结果如下:

[python] view plain copy

用Google搜索python时地址栏中URL的解析结果

('http', 'www.google.com', '/search', '',

'hl=en&q=python&btnG=Google+Search', '')

反解析python文档页面的URL

http://www.python.org/lib/module-urlparse.html

利用拼接方式添加更多python文档页面的URL

http://www.python.org/lib/module-urllib.html

http://www.python.org/lib/module-urllib2.html

http://www.python.org/lib/module-httplib.html

http://www.python.org/lib/module-cgilib.html

通过拼接子路径来生成Python文档页面的URL  

首先我们可以先获取要下载图片的整个页面信息。

getjpg.py

#coding=utf-8

import

urllib

def

getHtml(url):

page

=

urllib.urlopen(url)

html

=

page.read()

return

html

print

html

Urllib

模块提供了读取web页面数据的接口,我们可以像读取本地文件一样读取www和ftp上的数据。首先,我们定义了一个getHtml()函数:

urllib.urlopen()方法用于打开一个URL地址。

read()方法用于读取URL上的数据,向getHtml()函数传递一个网址,并把整个页面下载下来。执行程序就会把整个网页打印输出。

Python 中可以进行网页解析的库有很多,常见的有 BeautifulSoup 和 lxml 等。在网上玩爬虫的文章通常都是介绍 BeautifulSoup 这个库,我平常也是常用这个库,最近用 Xpath 用得比较多,使用 BeautifulSoup 就不大习惯,很久之前就知道 Reitz 大神出了一个叫 Requests-HTML 的库,一直没有兴趣看,这回可算歹着机会用一下了。

使用 pip install requests-html 安装,上手和 Reitz 的其他库一样,轻松简单:

这个库是在 requests 库上实现的,r 得到的结果是 Response 对象下面的一个子类,多个一个 html 的属性。所以 requests 库的响应对象可以进行什么操作,这个 r 也都可以。如果需要解析网页,直接获取响应对象的 html 属性:

不得不膜拜 Reitz 大神太会组装技术了。实际上 HTMLSession 是继承自 requests.Session 这个核心类,然后将 requests.Session 类里的 requests 方法改写,返回自己的一个 HTMLResponse 对象,这个类又是继承自 requests.Response,只是多加了一个 _from_response 的方法来构造实例:

之后在 HTMLResponse 里定义属性方法 html,就可以通过 html 属性访问了,实现也就是组装 PyQuery 来干。核心的解析类也大多是使用 PyQuery 和 lxml 来做解析,简化了名称,挺讨巧的。

元素定位可以选择两种方式:

方法名非常简单,符合 Python 优雅的风格,这里不妨对这两种方式简单的说明:

定位到元素以后势必要获取元素里面的内容和属性相关数据,获取文本:

获取元素的属性:

还可以通过模式来匹配对应的内容:

这个功能看起来比较鸡肋,可以深入研究优化一下,说不定能在 github 上混个提交。

除了一些基础操作,这个库还提供了一些人性化的操作。比如一键获取网页的所有超链接,这对于整站爬虫应该是个福音,URL 管理比较方便:

内容页面通常都是分页的,一次抓取不了太多,这个库可以获取分页信息:

结果如下:

通过迭代器实现了智能发现分页,这个迭代器里面会用一个叫 _next 的方法,贴一段源码感受下:

通过查找 a 标签里面是否含有指定的文本来判断是不是有下一页,通常我们的下一页都会通过 下一页 或者 加载更多 来引导,他就是利用这个标志来进行判断。默认的以列表形式存在全局: ['next','more','older'] 。我个人认为这种方式非常不灵活,几乎没有扩展性。 感兴趣的可以往 github 上提交代码优化。

也许是考虑到了现在 js 的一些异步加载,这个库支持 js 运行时,官方说明如下:

使用非常简单,直接调用以下方法:

第一次使用的时候会下载 Chromium,不过国内你懂的,自己想办法去下吧,就不要等它自己下载了。render 函数可以使用 js 脚本来操作页面,滚动操作单独做了参数。这对于上拉加载等新式页面是非常友好的。