刚好用到,这篇文章写得不错,转过来收藏。    转载自 道可道 | Python 标准库 urllib2 的使用细节

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

1 Proxy 的设置

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

import urllib2
 
enable_proxy = True
proxy_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 方法。

2 Timeout 设置

在老版本中,urllib2 的 API 并没有暴露 Timeout 的设置,要设置 Timeout 值,只能更改 Socket 的全局 Timeout 值。

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

在新的 Python 2.6 版本中,超时可以通过 urllib2.urlopen() 的 timeout 参数直接设置。

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

3 在 HTTP Request 中加入特定的 Header

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

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

对有些 header 要特别留意,Server 端会针对这些 header 做检查

  • User-Agent 有些 Server 或 Proxy 会检查该值,用来判断是否是浏览器发起的 Request
  • Content-Type 在使用 REST 接口时,Server 会检查该值,用来确定 HTTP Body 中的内容该怎样解析。

    常见的取值有:

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

    • ……

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

4 Redirect

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

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

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

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

5 Cookie

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

import urllib2
import cookielib
 
cookie = 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

6 使用 HTTP 的 PUT 和 DELETE 方法

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

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

这种做法虽然属于 Hack 的方式,但实际使用起来也没什么问题。

7 得到 HTTP 的返回码

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

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

8 Debug Log

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

import urllib2
 
httpHandler = 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')

python urllib2使用细节的更多相关文章

  1. python urllib2使用心得

    python urllib2使用心得 1.http GET请求 过程:获取返回结果,关闭连接,打印结果 f = urllib2.urlopen(req, timeout=10) the_page = ...

  2. python urllib2 模拟网站登陆

    python urllib2 模拟网站登陆 1. 可用浏览器先登陆,然后查看网页源码,分析登录表单 2. 使用python urllib2,cookielib 模拟网页登录 import urllib ...

  3. Python urllib2写爬虫时候每次request open以后一定要关闭

    最近用python urllib2写一个爬虫工具,碰到运行一会程序后就会出现scoket connection peer reset错误.经过多次试验发现原来是在每次request open以后没有及 ...

  4. python模块导入细节

    python模块导入细节 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码文件按照功能可以分为两种类型: ...

  5. python包导入细节

    包导入格式 导入模块时除了使用模块名进行导入,还可以使用目录名进行导入.例如,在sys.path路径下,有一个dir1/dir2/mod.py模块,那么在任意位置处都可以使用下面这种方式导入这个模块. ...

  6. 【转】python包导入细节

    [转]python包导入细节 包导入格式 导入模块时除了使用模块名进行导入,还可以使用目录名进行导入.例如,在sys.path路径下,有一个dir1/dir2/mod.py模块,那么在任意位置处都可以 ...

  7. 【转】python模块导入细节

    [转]python模块导入细节 python模块导入细节 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码 ...

  8. python urllib2详解及实例

    urllib2是Python的一个获取URLs(Uniform Resource Locators)的组件.他以urlopen函数的形式提供了一个非常简单的接口, 这是具有利用不同协议获取URLs的能 ...

  9. python urllib2介绍

    urllib2是Python的一个获取URLs(Uniform Resource Locators)的组件.他以urlopen函数的形式提供了一个非常简单的接口, 这是具有利用不同协议获取URLs的能 ...

随机推荐

  1. 聊聊Python中的GIL

    对于广大写Python的人来说,GIL(Global Interpreter Lock, 全局解释器锁)肯定不陌生,但未必清楚GIL的历史和全貌是怎样的,今天我们就来梳理一下GIL. 1. 什么是GI ...

  2. 【bzoj2238】Mst 最小生成树+树链剖分+线段树

    题目描述 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的边在下一条询问中依然存在) 输入 第一行两 ...

  3. P4712 「生物」能量流动

    由于题面$markdown$格式,博主太懒不想一个一个改,所以题面见此:戳 Solution: 本题的贪心思路比较有意思,完全考读题... 首先,因为总的能量来源是$a[0]$,所以可以理解为总能量守 ...

  4. [bzoj3270] 博物馆 [期望+高斯消元]

    题面 传送门 思路 本题的点数很少,只有20个 考虑用二元组$S=(u,v)$表示甲在$u$点,乙在$v$点的状态 那么可以用$f(S)$表示状态$S$出现的概率 不同的$f$之间的转移就是通过边 转 ...

  5. 51nod 1040 最大公约数之和 | 数论

    给出一个n,求1-n这n个数,同n的最大公约数的和 n<=1e9 考虑枚举每个因数,对答案贡献的就是个数*大小

  6. codeforces 834 D. The Bakery

    codeforces 834 D. The Bakery(dp + 线段树优化) 题意: 给一个长度为n的序列分成k段,每段的值为这一段不同数字的个数,最大化划分k端的值 $n <= 35000 ...

  7. Debian中文字体安装

    默认装的英文办的debian7,看中国字不太美,这好办照着做吧 1. Setup locales #dpkg-reconfigure locales 选择 zh_CN GB2312 zh_CN.GBK ...

  8. Android横竖屏总结(转)

    Android横竖屏总结(转) 横竖屏切换后Activity会重新执行onCreat函数,但是在Android工程的Mainfest.xml中加入android:screenOrientation=& ...

  9. fmap为什么可以用function作为第二个参数

    看看fmap的类型 fmap :: Functor f => (a -> b) -> f a -> f b 很明显的,第一个参数是function,第二个参数是functor的 ...

  10. [译] 如何像 Python 高手一样编程?

    转自:http://www.liuhaihua.cn/archives/23475.html Harries 发布于 7天前 分类:编程技术 阅读(15) 评论(0) 最近在网上看到一篇介绍Pytho ...