python - urllib2简介

来源:互联网 发布:.net域名续费价格 编辑:程序博客网 时间:2024/05/19 23:03

1、urllib和urllib2的关系
urllib 和 urllib2 都是接受URL请求的相关模块,但是提供了不同的功能,它们并不是可以相互代替的。

  • urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。这意味着,你不可以伪装你的User Agent字符串等。
  • urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。

如果仅做HTTP相关的,httplib2比其他几个模块好用。
2、简述urllib2
urlib2 是使用各种协议完成打开 url 的一个扩展包。最简单的使用方式是调用 urlopen() 方法,比如:

>>> import urllib2>>> f = urllib2.urlopen('http://www.sina.com')>>> a = f.read()>>> print a

即可以接受一个字符串型的 url 地址或者一个 Request 对象。将打开这个 url 并返回结果为一个像文件对象一样的对象。

urllib2模块和urllib模块类似,用来打开URL并从中获取数据。与urllib模块不同的是,urllib2模块不仅可以使用urlopen()函数还可以自定义opener来访问网页。但同时要注意:urlretrieve()函数是urllib模块中的,urllib2模块中不存在该函数。但是使用urllib2模块时一般都离不开urllib模块,因为post的数据需要使用urllib.urlencode()函数来编码。

下面介绍一下urllib2常用的方法。

urlopen(url, [,data, [timeout]])

urlopen()是最简单的请求方式,它打开url并返回类文件对象,并且使用该对象可以读取返回的内容。参数url可以是包含url的字符串,也可以是urllib2.request类的实例。data是经过编码的post数据(一般使用urllib.urlencode()来编码)。timeout是可选的超时期(以秒为单位),供所有阻塞操作内部使用。

假设urlopen()返回的文件对象u,它支持下面的这些常用的方法:

  • u.read([nbytes]) 以字节字符串形式读取nbytes个数据
  • u.readline() 以字节字符串形式读取单行文本
  • u.readlines() 读取所有输入行然后返回一个列表
  • u.close() 关闭链接
  • u.getcode() 返回整数形式的HTTP响应代码,比如成功返回200,未找到文件时返回404
  • u.geturl() 返回所返回的数据的实际url,但是会考虑发生的重定向问题
  • u.info() 返回映射对象,该对象带有与url关联的信息,对HTTP来说,返回的服务器响应包含HTTP包头。对于FTP来说,返回的报头包含’content-length’。对于本地文件,返回的报头包含‘content-length’和’content-type’字段。

要注意的是,类文件对象u以二进制模式操作。如果需要以文本形式处理响应数据,则需要使用codecs模块或类似方式解码数据。

Request (url [data,headers [,origin_req_host ,[unverifiable]]]])

对于比较简单的请求,urlopen()的参数url就是一个代表url的但如果需要执行更复杂的操作,如修改HTTP报头,可以创建Request实例并将其作为url参数。

新建Request实例。url为url字符串,data是伴随url提交的数据(比如要post的数据)。不过要注意,提供data参数时,它会将HTTP请求从’GET’改为‘POST’。headers是一个字典,包含了可表示HTTP报头的键值映射(即要提交的header中包含的内容)。originreqhost通常是发出请求的主机的名称,如果请求的是无法验证的url(通常是指不是用户直接输入的url,比如加载图像的页面中镶入的url),则后一个参数unverifiable设为TRUE。

假设Request实例r,其比较重要的方法有下面几个:

  • r.add_data(data) 向请求添加数据。如果请求是HTTP请求,则方法改为‘POST’。data是向指定url提交的数据,要注意该方法不会将data追教导之前已经设置的任何数据上,而是使用现在的data替换之前的。
  • r.add_header(key, val) 向请求添加header信息,key是报头名,val是报头值,两个参数都是字符串。
  • r.addunredirectedheader(key, val) 作用基本同上,但不会添加到重定向请求中。
  • r.set_proxy(host, type) 准备请求到服务器。使用host替换原来的主机,使用type替换原来的请求类型。

Proxy 的设置

urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy。如果想在程序中明确控制 Proxy 而不受环境变量的影响,可以使用下面的方式:

import urllib2enable_proxy = Trueproxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'})null_proxy_handler = urllib2.ProxyHandler({})if enable_proxy:    opener = urllib2.build_opener(proxy_handler)else:    opener = urllib2.build_opener(null_proxy_handler)urllib2.install_opener(opener)

这里要注意的一个细节,使用 urllib2.install_opener() 会设置 urllib2 的全局 opener 。这样后面的使用会很方便,但不能做更细粒度的控制,比如想在程序中使用两个不同的 Proxy 设置等。比较好的做法是不使用 install_opener 去更改全局的设置,而只是直接调用 opener 的 open 方法代替全局的 urlopen 方法。

Timeout 设置

在老版 Python 中,urllib2 的 API 并没有暴露 Timeout 的设置,要设置 Timeout 值,只能更改 Socket 的全局 Timeout 值。
在 Python 2.6 以后,超时可以通过 urllib2.urlopen() 的 timeout 参数直接设置。

import urllib2response = urllib2.urlopen('http://www.google.com', timeout=10)

在 HTTP Request 中加入特定的 Header

要加入 header,需要使用 Request 对象:

import urllib2request = urllib2.Request(uri)request.add_header('User-Agent', 'fake-client')response = urllib2.urlopen(request)

对有些 header 要特别留意,服务器会针对这些 header 做检查:

  • User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求。
  • Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。常见的取值有:

    • application/xml : 在 XML RPC,如 RESTful/SOAP 调用时使用
    • application/json : 在 JSON RPC 调用时使用
    • application/x-www-form-urlencoded : 浏览器提交 Web 表单时使用

在使用服务器提供的 RESTful 或 SOAP 服务时, Content-Type 设置错误会导致服务器拒绝服务

Redirect

urllib2 默认情况下会针对 HTTP 3XX 返回码自动进行 redirect 动作,无需人工配置。要检测是否发生了 redirect 动作,只要检查一下 Response 的 URL 和 Request 的 URL 是否一致就可以了。

import urllib2response = urllib2.urlopen('http://www.google.cn')redirected = response.geturl() == 'http://www.google.cn'

如果不想自动 redirect,除了使用更低层次的 httplib 库之外,还可以自定义 HTTPRedirectHandler 类。

import urllib2class RedirectHandler(urllib2.HTTPRedirectHandler):    def http_error_301(self, req, fp, code, msg, headers):        pass    def http_error_302(self, req, fp, code, msg, headers):        passopener = urllib2.build_opener(RedirectHandler)opener.open('http://www.google.cn')

Cookie

urllib2 对 Cookie 的处理也是自动的。如果需要得到某个 Cookie 项的值,可以这么做:

import urllib2import cookielibcookie = cookielib.CookieJar()opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))response = opener.open('http://www.google.com')for item in cookie:    if item.name == 'some_cookie_item_name':        print item.value

使用 HTTP 的 PUT 和 DELETE 方法

urllib2 只支持 HTTP 的 GET 和 POST 方法,如果要使用 HTTP PUT 和 DELETE ,只能使用比较低层的 httplib 库。虽然如此,我们还是能通过下面的方式,使 urllib2 能够发出 PUT 或 DELETE 的请求:

import urllib2request = urllib2.Request(uri, data=data)request.get_method = lambda: 'PUT' # or 'DELETE'response = urllib2.urlopen(request)

得到 HTTP 的返回码

对于 200 OK 来说,只要使用 urlopen 返回的 response 对象的 getcode() 方法就可以得到 HTTP 的返回码。但对其它返回码来说,urlopen 会抛出异常。这时候,就要检查异常对象的 code 属性了:

import urllib2try:    response = urllib2.urlopen('http://restrict.web.com')except urllib2.HTTPError, e:    print e.code

Debug Log

使用 urllib2 时,可以通过下面的方法把 debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便调试,有时可以省去抓包的工作。

import urllib2httpHandler = urllib2.HTTPHandler(debuglevel=1)httpsHandler = urllib2.HTTPSHandler(debuglevel=1)opener = urllib2.build_opener(httpHandler, httpsHandler)urllib2.install_opener(opener)response = urllib2.urlopen('http://www.google.com')

REFERENCE

0 0
原创粉丝点击