Python Requests Libraries

来源:互联网 发布:剑灵龙族男捏脸数据 编辑:程序博客网 时间:2024/06/08 09:52

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 requestsimport jsonr = 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#输出 200r = requests.get('http://www.mengtiankong.com/123123/')print r.status_code#输出 404r=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']#输出: gzipr.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 。

原创粉丝点击