度过了一个冬眠,在春末夏初之际,补充自己的营养,努力学习,努力工作!

Python 标准库 urllib2 的使用细节

上一篇 / 下一篇  2014-07-07 18:05:43 / 个人分类:python

A?{BJ _Q\0转自:http://zhuoqiang.me/python-urllib2-usage.html51Testing软件测试网&cB%Wcp+Yy

~MOq0V a uD^*_051Testing软件测试网o L?L0P2}y&]p

Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库。这里总结了一些 urllib2 的使用细节。

+b0uF+sF%Lm,q5s0

Proxy 的设置

51Testing软件测试网O6v L S#j'f0]\h[

urllib2 默认会使用环境变量http_proxy来设置 HTTP Proxy。如果想在程序中明确控制 Proxy 而不受环境变量的影响,可以使用下面的方式51Testing软件测试网LBh:RX/U$J R;Z

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

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

*M8O3g c6j ~A d0

Timeout 设置

x*P4s/@7K6]l,~Yx9d0在老版 Python 中,urllib2 的 API 并没有暴露 Timeout 的设置,要设置 Timeout 值,只能更改 Socket 的全局 Timeout 值。

REVva9e:T0
importurllib2importsocketsocket.setdefaulttimeout(10)# 10 秒钟后超时urllib2.socket.setdefaulttimeout(10)# 另一种方式
51Testing软件测试网7LMk\"L

在 Python 2.6 以后,超时可以通过urllib2.urlopen()timeout参数直接设置。

I k8y1u~0
importurllib2response=urllib2.urlopen('http://www.google.com',timeout=10)

在 HTTP Request 中加入特定的 Header

c't8mU:p*`0要加入 header,需要使用Request对象:

6~ l2b6N;M?ET0
importurllib2request=urllib2.Request(uri)request.add_header('User-Agent','fake-client')response=urllib2.urlopen(request)

_u:T@'c,AE0对有些 header 要特别留意,服务器会针对这些 header 做检查

Y;kwQ g)hS8A0
  • User-Agent: 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求

    Sp j6U8T0
  • Content-Type: 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。常见的取值有:

    W%T$DNK+kk0T9`0
    • application/xml: 在 XML RPC,如 RESTful/SOAP 调用时使用
    • application/json: 在 JSON RPC 调用时使用
    • application/x-www-form-urlencoded: 浏览器提交 Web 表单时使用
    51Testing软件测试网ruoL)p!h

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

    P ],\v @,M7_,z#gr0

Redirect

51Testing软件测试网-t9R{N-xu8a6ch^n

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

$`-` Be+u4?R,m#d0
importurllib2response=urllib2.urlopen('http://www.google.cn')redirected=response.geturl()=='http://www.google.cn'
51Testing软件测试网:O.x%]jG}#B

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

+C'J5s&B1{^(}&Xh0
importurllib2classRedirectHandler(urllib2.HTTPRedirectHandler):defhttp_error_301(self,req,fp,code,msg,headers):passdefhttp_error_302(self,req,fp,code,msg,headers):passopener=urllib2.build_opener(RedirectHandler)opener.open('http://www.google.cn')

使用 HTTP 的 PUT 和 DELETE 方法

s3}A4U8Z(i6^K0urllib2 只支持 HTTP 的GETPOST方法,如果要使用 HTTPPUTDELETE,只能使用比较低层的 httplib 库。虽然如此,我们还是能通过下面的方式,使 urllib2 能够发出PUTDELETE的请求:51Testing软件测试网 ^Hf;dI

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

[8d r] o,q'D@^0这种做法虽然属于 Hack 的方式,但实际使用起来也没什么问题。51Testing软件测试网9d7lvw$v-?]

得到 HTTP 的返回码

51Testing软件测试网R$f5Mo^:Eh Zu

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

importurllib2try:response=urllib2.urlopen('http://restrict.web.com')excepturllib2.HTTPError,e:printe.code

Debug Log

51Testing软件测试网.}/IS{!D+?LL#[*o

使用 urllib2 时,可以通过下面的方法把 debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便调试,有时可以省去抓包的工作51Testing软件测试网/F|(~6t'Tq:~;r

importurllib2httpHandler=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')51Testing软件测试网3iI1IF~G
51Testing软件测试网WDs7m7W'zU

TAG:

 

评分:0

我来说两句

Open Toolbar