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

Python 标准库 urllib2 的使用细节

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

51Testing软件测试网 N.CPJB,]9t$K

转自:http://zhuoqiang.me/python-urllib2-usage.html
K A ]J \_9p051Testing软件测试网 |UG#{!l[Fx'EW

y-]0v5YzH0Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库。这里总结了一些 urllib2 的使用细节。51Testing软件测试网)z@ Dgh;P{A ]

Proxy 的设置

51Testing软件测试网)\7[ H-mQ6p$Da

urllib2 默认会使用环境变量http_proxy来设置 HTTP Proxy。如果想在程序中明确控制 Proxy 而不受环境变量的影响,可以使用下面的方式51Testing软件测试网X V9Y'Pk*?rp3?]$@ }

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)
51Testing软件测试网_VG.t,T:I?'x+O

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

VX GK$a(b9}^0

Timeout 设置

H2JJ p[P0在老版 Python 中,urllib2 的 API 并没有暴露 Timeout 的设置,要设置 Timeout 值,只能更改 Socket 的全局 Timeout 值。51Testing软件测试网*@/k:Zp+m A,}ow

importurllib2importsocketsocket.setdefaulttimeout(10)# 10 秒钟后超时urllib2.socket.setdefaulttimeout(10)# 另一种方式

J q6sU&lZo s j Z0在 Python 2.6 以后,超时可以通过urllib2.urlopen()timeout参数直接设置。

%Z+q A9^"qy0
importurllib2response=urllib2.urlopen('http://www.google.com',timeout=10)

在 HTTP Request 中加入特定的 Header

51Testing软件测试网9L)N9pc!^b

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

s:S4aNo?+`S7I0
importurllib2request=urllib2.Request(uri)request.add_header('User-Agent','fake-client')response=urllib2.urlopen(request)

7k&]/|j8leP0对有些 header 要特别留意,服务器会针对这些 header 做检查

h:DM F7Q0
  • User-Agent: 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求

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

    dD,bo6hav0
    • application/xml: 在 XML RPC,如 RESTful/SOAP 调用时使用
    • application/json: 在 JSON RPC 调用时使用
    • application/x-www-form-urlencoded: 浏览器提交 Web 表单时使用
    51Testing软件测试网 S+_2G2NgT0O1Z

    在使用服务器提供的 RESTful 或 SOAP 服务时,Content-Type设置错误会导致服务器拒绝服务51Testing软件测试网] kICR0uu

Redirect

51Testing软件测试网a4LC|3u6G3[[

urllib2 默认情况下会针对 HTTP 3XX 返回码自动进行 redirect 动作,无需人工配置。要检测是否发生了 redirect 动作,只要检查一下Response的 URL 和Request的 URL 是否一致就可以了。51Testing软件测试网9\(M q ^!O:]j5Cm%F$z

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

5zIbM O]0\MhR0如果不想自动 redirect,除了使用更低层次的 httplib 库之外,还可以自定义HTTPRedirectHandler类。51Testing软件测试网3\.D{;]c/v%KM

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 方法

51Testing软件测试网]3Z'Vk9s

urllib2 只支持 HTTP 的GETPOST方法,如果要使用 HTTPPUTDELETE,只能使用比较低层的 httplib 库。虽然如此,我们还是能通过下面的方式,使 urllib2 能够发出PUTDELETE的请求:51Testing软件测试网-F AU8`J:QX-l$] f

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

E[;r!jk d;P#t0这种做法虽然属于 Hack 的方式,但实际使用起来也没什么问题。

\ fK ]%W9B~ g0

得到 HTTP 的返回码

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

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

Debug Log

F1QIXD:F`1i0使用 urllib2 时,可以通过下面的方法把 debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便调试,有时可以省去抓包的工作51Testing软件测试网kv+y#C9qp

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软件测试网(VB,o:~~ C$Xt

MEX'Hnj*L0fx-p&T0

TAG:

 

评分:0

我来说两句

Open Toolbar