Python Requests Libraries

requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到。可以说,Requests 完全满足如今网络的需求


发送请求与传递参数

先来一个简单的例子
有时候我们需要在URL中传递参数,比如在采集百度搜索结果时,我们wd参数(搜索词)和rn参数(搜素结果数量),你可以手工组成URL,requests也提供了一种看起来很NB的方法:

payload = {'wd': '张亚楠', 'rn': '100'}
r = requests.get("http://www.baidu.com/s", params=payload)
print r.url

输出:
u’http://www.baidu.com/s?rn=100&wd=%E5%BC%A0%E4%BA%9A%E6%A5%A0
上面wd=的乱码就是“张亚楠”的转码形式。(好像参数按照首字母进行了排序。)


Response对象

使用requests方法后,会返回一个response对象,其存储了服务器响应的内容,如上实例中已经提到的 r.text、r.status_code……
获取文本方式的响应体实例:当你访问 r.text 之时,会使用其响应的文本编码进行解码,并且你可以修改其编码让 r.text 使用自定义的编码进行解码。

r = requests.get('http://www.baidu.com')
print(r.text, '\n{}\n'.format('*'*79), r.encoding)
r.encoding = 'GBK'
print(r.text, '\n{}\n'.format('*'*79), r.encoding)

其他响应:

r.status_code #响应状态码
r.raw #返回原始响应体,也就是 urllib 的 response 对象,使用 r.raw.read() 读取
r.content #字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩
r.text #字符串方式的响应体,会自动根据响应头部的字符编码进行解码,返回headers中的编码解析的结果
r.headers #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None
#*特殊方法*#
r.json() #Requests中内置的JSON解码器
r.raise_for_status() #失败请求(非200响应)抛出异常

获取网页编码

可以使用r.encoding来获取网页编码。

r = requests.get('http://www.zhidaow.com')
print r.encoding

#输出'utf-8'

当你发送请求时,requests会根据HTTP头部来猜测网页编码,当你使用r.text时,requests就会使用这个编码。当然你还可以修改requests的编码形式。

r = requests.get('http://www.zhidaow.com')
r.encoding = 'ISO-8859-1'

像上面的例子,对encoding修改后就直接会用修改后的编码去获取网页内容。


json

就要引入新模块,如json和simplejson,但在requests中已经有了内置的函数,r.json()。就拿查询IP的API来说:

import requests
import json

r = requests.get('http://ip.taobao.com/service/getIpInfo.php?ip=122.88.60.28')
print r.json()['data']['country']

输出: 中国

如果 JSON 解码失败, r.json() 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json() 将会抛出 ValueError: No JSON object could be decoded 异常。

需要注意的是,成功调用 r.json() 并意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象(比如 HTTP 500 的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status() 或者检查 r.status_code 是否和你的期望相同。


网页状态码

我们可以用r.status_code来检查网页的状态码。

r = requests.get('http://www.mengtiankong.com')
print r.status_code
#输出 200
r = requests.get('http://www.mengtiankong.com/123123/')
print r.status_code
#输出 404
r=requests.get('http://www.baidu.com/linkurl=QeTRFOS7TuUQRppa0wlTJJr6FfIYI1DJprJukx4Qy0XnsDO_s9baoO8u1wvjxgqN')
print r.url
#输出 u'http://www.zhidaow.com/
print r.status_code
#输出 200

前两个例子很正常,能正常打开的返回200,不能正常打开的返回404。但第三个就有点奇怪了,那个是百度搜索结果中的302跳转地址,但状态码显示是200,接下来我用了一招让他原形毕露:

print r.history
#输出 (<Response [302]>,)

这里能看出他是使用了302跳转。也许有人认为这样可以通过判断和正则来获取跳转的状态码了,其实还有个更简单的方法:

r = requests.get('http://www.baidu.com/link?url=QeTRFOS7TuUQRppa0wlTJJr6FfIYI1DJprJukx4Qy0XnsDO_s9baoO8u1wvjxgqN', allow_redirects = False)

print r.status_code
#输出 302

只要加上一个参数allow_redirects,禁止了跳转,就直接出现跳转的状态码了,好用吧?我也利用这个在最后一掌做了个简单的获取网页状态码的小应用,原理就是这个。


响应头内容

可以通过r.headers来获取响应头内容。

r = requests.get('http://www.baidu.com')
print r.headers

输出:
{
‘content-encoding’: ‘gzip’,
‘transfer-encoding’: ‘chunked’,
‘Set-Cookie’: ‘BDORZ=27315
‘Transfer-Encoding’: ‘chunked’, ;
max-age=86400;
domain=.baidu.com

}
可以看到是以字典的形式返回了全部内容,我们也可以访问部分内容。

r.headers['content-encoding']
#输出: gzip

r.headers.get('content-encoding')
#输出: gzip

请求头内容

请求头内容可以用r.request.headers来获取。

r.request.headers

输出:
{‘Accept-Encoding’: ‘identity, deflate, compress, gzip’,
‘Accept’: ‘/‘, ‘User-Agent’: ‘python-requests/1.2.3 CPython/2.7.3 Windows/XP’}


设置超时时间

我们可以通过timeout属性设置超时时间,一旦超过这个时间还没获得响应内容,就会提示错误。

requests.get('http://github.com', timeout=0.001)

timeout 仅对连接过程有效,与响应体的下载无关。 timeout 并不是整个下载响应的时间限制,而是如果服务器在 timeout 秒内没有应答,将会引发一个异常(更精确地说,是在 timeout 秒内没有从基础套接字上接收到任何字节的数据时)


如果某个响应中包含一些 cookie,你可以快速访问它们:

url = 'http://example.com/some/cookie/setting/url'
r = requests.get(url)

r.cookies['example_cookie_name']
#输出 'example_cookie_value'

要想发送你的cookies到服务器,可以使用 cookies 参数:

url = 'http://httpbin.org/cookies'
cookies = dict(cookies_are='working')

r = requests.get(url, cookies=cookies)
print r.text
#输出 '{"cookies": {"cookies_are": "working"}}'

Cookie 的返回对象为 RequestsCookieJar,它的行为和字典类似,但界面更为完整,适合跨域名跨路径使用。你还可以把 Cookie Jar 传到 Requests 中:

jar = requests.cookies.RequestsCookieJar()
jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
url = 'http://httpbin.org/cookies'
r = requests.get(url, cookies=jar)
print r.text
#输出 '{"cookies": {"tasty_cookie": "yum"}}'

错误与异常

遇到网络问题(如:DNS 查询失败、拒绝连接等)时,Requests 会抛出一个 ConnectionError 异常。

如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常。

若请求超时,则抛出一个 Timeout 异常。

若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。

所有Requests显式抛出的异常都继承自 requests.exceptions.RequestException 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值