简介:
urllib2是python的一个获取url(Uniform Resource Locators,统一资源定址器)的模块。它用urlopen函数的形式提供了一个非常简洁的接口。这使得用各种各样的协议获取url成为可能。它同时 也提供了一个稍微复杂的接口来处理常见的状况-如基本的认证,cookies,代理,等等。这些都是由叫做opener和handler的对象来处理的。

以下是获取url最简单的方式:

import urllib2
response = urllib2.urlopen('http://python.org/')
html = response.read()

许多urlib2的使用都是如此简单(注意我们本来也可以用一个以”ftp:”"file:”等开头的url取代”HTTP”开头的url).然 而,这篇教程的目的是解释关于HTTP更复杂的情形。HTTP建基于请求和回应(requests &responses )-客户端制造请求服务器返回回应。urlib2用代 表了你正在请求的HTTP request的Request对象反映了这些。用它最简单的形式,你建立了一个Request对象来明确指明你想要获取的url。调用urlopen函 数对请求的url返回一个respons对象。这个respons是一个像file的对象,这意味着你能用.read()函数操作这个respon对象:

import urllib2

req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)
the_page = response.read()

注意urlib2利用了同样的Request接口来处理所有的url协议。例如,你可以像这样请求一个ftpRequest:

req = urllib2.Request('ftp://example.com/')

对于HTTP,Request对象允许你做两件额外的事:第一,你可以向服务器发送数据。第二,你可以向服务器发送额外的信息(metadata),这些信息可以是关于数据本身的,或者是关于这个请求本身的–这些信息被当作HTTP头发送。让我们依次看一下这些。

数据:
有时你想向一个URL发送数据(通常这些数据是代表一些CGI脚本或者其他的web应用)。对于HTTP,这通常叫做一个Post。当你发送一个你 在网上填的form(表单)时,这通常是你的浏览器所做的。并不是所有的Post请求都来自HTML表单,这些数据需要被以标准的方式encode,然后 作为一个数据参数传送给Request对象。Encoding是在urlib中完成的,而不是在urlib2中完成的。

import urllib
import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }

data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()

如果你不传送数据参数,urlib2使用了一个GET请求。一个GET请求和POST请求的不同之处在于POST请求通常具有边界效应:它们以某种 方式改变系统的状态。(例如,通过网页设置一条指令运送一英担罐装牛肉到你家。)虽然HTTP标准清楚的说明Post经常产生边界效应,而get从不产生 边界效应,但没有什么能阻止一个get请求产生边界效应,或一个Post请求没有任何边界效应。数据也能被url自己加密(Encoding)然后通过一 个get请求发送出去。

这通过以下实现:
>>> import urllib2
>>> import urllib
>>> data = {}
>>> data['name'] = 'Somebody Here'
>>> data['location'] = 'Northampton'
>>> data['language'] = 'Python'
>>> url_values = urllib.urlencode(data)
>>> print url_values
name=Somebody+Here&language=Python&location=Northampton
>>> url = 'http://www.example.com/example.cgi'
>>> full_url = url + '?' + url_values
>>> data = urllib2.open(full_url)

头:
我们将会在这里讨论一个特殊的HTTP头,来阐释怎么向你的HTTP请求中加入头。
有一些网站不希望被某些程序浏览或者针对不同的浏览器返回不同的版本。默认情况下,urlib2把自己识别为Python-urllib/x.y(这里的 xy是python发行版的主要或次要的版本号,如, Python-urllib/2.5),这些也许会混淆站点,或者完全不工作。浏览器区别自身的方式是通过User-Agent头。当你建立一个 Request对象时,你可以加入一个头字典。接下来的这个例子和上面的请求一样,不过它把自己定义为IE的一个版本。

import urllib
import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }
headers = { 'User-Agent' : user_agent }

data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

Respons同样有两种有用的方法。当我们出差错之后,看一下关于info and geturl的部分。

异常处理:

不能处理一个respons时,urlopen抛出一个urlerror(虽然像平常一样对于python APIs,内建异常如,ValueError, TypeError 等也会被抛出。)
HTTPerror是HTTP URL在特别的情况下被抛出的URLError的一个子类。
urlerror:
通常,urlerror被抛出是因为没有网络连接(没有至特定服务器的连接)或者特定的服务器不存在。在这种情况下,含有reason属性的异常将被抛出,以一种包含错误代码和文本错误信息的tuple形式。

e.g.
>>> req = urllib2.Request('http://www.pretend_server.org')
>>> try: urllib2.urlopen(req)
>>> except URLError, e:
>>> print e.reason
>>>
(4, 'getaddrinfo failed')

当一个错误被抛出的时候,服务器返回一个HTTP错误代码和一个错误页。你可以使用返回的HTTP错误示例。这意味着它不但具有code属性,而且 同时具有read,geturl,和info,methods属性。>>> req = urllib2.Request('http://www.python.org/fish.html')>>> try:>>> urllib2.urlopen(req)>>> except URLError, e:>>> print e.code>>> print e.read()>>>404...... etc

容错:
如果你准备处理HTTP错误和URL错误这里有两种基本的方法,我更倾向于后一种:

1.
from urllib2 import Request, urlopen, URLError, HTTPError
req = Request(someurl)
try:
response = urlopen(req)
except HTTPError, e:
print 'The server couldn\'t fulfill the request.'
print 'Error code: ', e.code
except URLError, e:
print 'We failed to reach a server.'
print 'Reason: ', e.reason
else:
# everything is fine

注意:HTTP错误异常必须在前面,否则URL错误也会捕获一个HTTP错误。
2
from urllib2 import Request, urlopen, URLError
req = Request(someurl)
try:
response = urlopen(req)
except URLError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server couldn\'t fulfill the request.'
print 'Error code: ', e.code
else:
# everything is fine

注意:URL错误是IO错误异常的一个子类。这意味着你能避免引入(import)URL错误而使用:

from urllib2 import Request, urlopen
req = Request(someurl)
try:
response = urlopen(req)
except IOError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server couldn\'t fulfill the request.'
print 'Error code: ', e.code
else:
# everything is fine

极少数环境下,urllib2能够抛出socket.error.

INFO and GETURL
urlopen返回的response(或者HTTP错误实例)有两个有用的方法:info和geturl。

geturl–它返回被获取网页的真正的url。这是很有用的,因为urlopen(或使用的opener对象)也许会伴随一个重定向。
获取的网页url也许和要求的网页url不一样。

info–它返回一个像字典的对象来描述获取的网页,尤其是服务器发送的头。它现在一般是httplib.HTTPMessage的一个实例。
典型的头包含'Content-length', 'Content-type', 等等。看一下Quick Reference to HTTP Headers中,HTTP头列表,还有
关于他们简单的解释和使用方法。
Openers 和Handlers
当你获取一个URL时,你使用一个opener(一个可能以一个比较迷糊名字命名的实例–urllib2.OpenerDirector)。正常情况下
我们一直使用默认的opener,通过urlopen,但你也可以创建自定义的openers。opener使用操作器(handlers)。所有的重活都交给这些handlers来做。每一个handler知道
怎么打开url以一种独特的url协议(http,ftp等等),或者怎么处理打开url的某些方面,如,HTTP重定向,或者HTTP cookie。

你将会创建openers如果你想要用安装特别的handlers获取url,例如,获取一个处理cookie的opener,或者一个不处理重定向的opener。

枚举一个OpenerDirector,然后多次调用.add_handler(some_handler_instance)来创建一个opener。
或者,你可以用build_opener,这是一个很方便的创建opener对象的函数,它只有一个函数调用。build_opener默认会加入许多
handlers,但是提供了一个快速的方法添加更多东西和/或使默认的handler失效。
其他你想要的handlers能够处理代理,authentication和其他平常但是又有些特殊的情况。
install_opener能被用于创建一个opener对象,(全局)默认的opener。这意味着调用urlopen将会用到你刚安装的opener。
opener对象有一个open方法,它可以被直接调用来获取url以一种和urlopen函数同样的方式:没有必要调用install_opener,除非是为了方便。

Basic Authentication:(基本验证)

为了解释创建和安装一个handler,我们将会使用 HTTPBasicAuthHandler。更多关于这个东西的内容和详细讨论—包括一个 Basic Authentication如何工作的解说–参见 Basic Authentication Tutorial.

当需要Authentication的时候,服务器发送一个头(同时还有401代码)请求Authentication。它详细指明了一个Authentication和一个域。这个头看起来像:

Www-authenticate: SCHEME realm=”REALM”.
e.g.
Www-authenticate: Basic realm=”cPanel Users”

客户端然后就会用包含在头中的正确的帐户和密码重新请求这个域。这是”基本验证”。为了简化这个过程,我们可以创建一个
HTTPBasicAuthHandler和opener的实例来使用这个handler。
HTTPBasicAuthHandler用一个叫做密码管理的对象来处理url和用户名和密码的域的映射。如果你知道域是什么(从服务器发送的authentication
头中),那你就可以使用一个HTTPPasswordMgr。多数情况下人们不在乎域是什么。那样使用HTTPPasswordMgrWithDefaultRealm就很方便。它
允许你为一个url具体指定用户名和密码。这将会在你没有为一个特殊的域提供一个可供选择的密码锁时提供给你。我们通过提供None作为add_password方法域的参数指出
这一点。
最高级别的url是需要authentication的第一个url。比你传递给.add_password()的url更深的url同样也会匹配。

# create a password manager
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
# If we knew the realm, we could use it instead of “None“.
top_level_url = “http://example.com/foo/”
password_mgr.add_password(None, top_level_url, username, password)

handler = urllib2.HTTPBasicAuthHandler(password_mgr)
# create “opener” (OpenerDirector instance)
opener = urllib2.build_opener(handler)
# use the opener to fetch a URL
opener.open(a_url)
# Install the opener.
# Now all calls to urllib2.urlopen use our opener.
urllib2.install_opener(opener)

注意:在以上的示例中我们只给build_opener提供了HTTPBasicAuthHandler。默认opener有对普通情况的操作器 (handlers)- ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor.
高级别url实际上是一个完整的url(包括http:协议组件和主机名可选的端口号),如”http://example.com”或者是一个授权(同样,主机名,可选的端口号)
如”"example.com” 或 “example.com:8080″(后一个示例包含了一个端口号)。授权,如果被呈现,一定不能包含用户信息-如”oe@password:example.com”
是不正确的、
代理:
urllib2将会自动检测你的代理设置并使用它们。这是通过 ProxyHandler实现的,它是操作器链的一部分。正常情况下,这是个好东西,但是也有它不那么有用的偶然情况。
一个做这些的方法是安装我们自己的ProxyHandler,不用任何定义任何代理。使用一个和建立Basic Authentication操作器相似的步骤可以实现:

>>> proxy_support = urllib2.ProxyHandler({})
>>> opener = urllib2.build_opener(proxy_support)
>>> urllib2.install_opener(opener)
注意:
目前urllib2不支持通过代理获取HTTPs位置。这是一个问题。
sockets和layers
python支持获取层叠的网页的源码。urllib2使用httplib library,而httplib library反过来使用socket library。
对于python2.3你可以指明一个socket应该在超时之前等待response多久。这在这些不得不获取网页的应用中很有用。默认socket模块没有超时而且能够挂起。
目前,socket超时在urllib2或者httplib水平中不可见。然而,你可以全局地为所有socket设置默认的超时。

import socket
import urllib2
# timeout in seconds
timeout = 10
socket.setdefaulttimeout(timeout)
# this call to urllib2.urlopen now uses the default timeout
# we have set in the socket module
req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)

转载于:https://www.cnblogs.com/appleface/archive/2012/10/19/2730943.html

urllib2介绍(转)相关推荐

  1. 《深入Python》-11. HTTP Web 服务

    <深入Python>-11. HTTP Web 服务 11. HTTP Web 服务 出处: http://www.woodpecker.org.cn/diveintopython/htt ...

  2. Python urllib和urllib2模块学习(一)

    (参考资料:现代魔法学院 http://www.nowamagic.net/academy/detail/1302803) Python标准库中有许多实用的工具类,但是在具体使用时,标准库文档上对使用 ...

  3. python爬虫requests-Python爬虫之requests介绍

    一.基本介绍 和urllib.urllib2的区别: requests不是标准库 最好用的http库,pythonic风格 安装:pip install requests 二.requests请求 1 ...

  4. Python进阶10-标准库介绍01

    摘要:Python标准库介绍 Python的一大好处在于它有一套很有用的标准库(standard library).标准库是随着Python一起安装在你的电脑中的,是Python的一部分 (当然也有特 ...

  5. python selenium采集速卖通_2.不苟的爬虫小教程系列:python爬虫技术栈介绍

    鉴于爬虫初学者们,往往也是编程的初学者,我在这里介绍一套最常用的技术栈,不求多,只求精. 毕竟我们的目标是采集到数据,只要能够成功实现目标的工具就是好工具. 爬虫框架scrapy:该框架是scrapi ...

  6. python requests和urllib_Python——深入理解urllib、urllib2及requests(requests不建议使用?)...

    深入理解urllib.urllib2及requests Python 是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年, ...

  7. Python urllib2和urllib的使用

    Python urllib2和urllib的使用 在Python中有很多库可以用来模拟浏览器发送请求抓取网页,本文中介绍使用urllib2来实现获取网页数据. urllib2是在Python2标准库中 ...

  8. 爬虫开发.1爬虫介绍

    一.urllib库 概念:urllib是Python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在Python3中的为urllib.request和urll ...

  9. awk命令详解_python学习之利用urllib和urllib2访问http的GET/POST详解

    前言 本文主要给大家介绍了关于python如何学习访问http的GET/POST的相关内容,使用urllib和urllib2,可以轻松实现对http的访问,下面话不多说了,来一起看看详细的介绍吧. 示 ...

最新文章

  1. java 有界类型_Java™ 教程(有界类型参数)
  2. LeetCode 426. Convert Binary Search Tree to Sorted Doubly Linked List--转换二叉树为双向链表--Java,C++,Python解法
  3. 例说DNS递归/迭代名称解析原理
  4. 关于Java函数传参以及参数在函数内部改变的问题——JAVA值传递与引用最浅显的说明!...
  5. java计算代码执行时间
  6. android下拉会谈效果,Android实现下拉展示条目效果
  7. mysql-5.5.31主从复制
  8. 48session的生命周期
  9. javascript jquery ajax动态提交多个参数 api测试
  10. Java:MySQL5.5安装教程
  11. struts2之自定义拦截器及拦截器生命周期分析
  12. 决策树结果可视化中文乱码问题解决方案
  13. ros打开笔记本电脑的摄像头
  14. android脚本 附近的人,安卓引流脚本好用吗,附近的人引流脚本的功能你知道几个?...
  15. 应用VBS修改注册表大全
  16. java拼接sql语句的in条件
  17. 主流的深度学习优化方法(SGD,SGDM,Adagrad,RMSProp,Adam)
  18. 前Vertu设计师推出Android版iBeacon,无需专有硬件,没话费的旧手机都能做基站
  19. python中哪些是无序_关于无序集合:无序集合 – 在python中设置
  20. LC串联谐振的意义-MOS管栅极G串联电阻

热门文章

  1. oracle银行卡号检查约束,oracle约束学习(1)unique和check
  2. Zookeeper分布式一致性原理(二):一致性协议
  3. Java设计模式(二十一):备忘录设计模式
  4. 机房速度和带宽测试的简单方法
  5. 通过模拟器看Windows Phone 7
  6. TP自动生成模块目录
  7. SpringBoot日记——ElasticSearch全文检索
  8. Redis 哨兵模式 带密码单机
  9. 屠龙之路_战胜View对DataBase猛烈进攻_ThirdDay
  10. 2016 大连网赛---Different GCD Subarray Query(GCD离散+树状数组)