requests payload_RESTful API系列之无敌requests模块

今天RESTfulAPI 系列继续。

之前咱们讲过了http的基础以及什么是RESTful API,我想大家都有一个直观简单的认识了。今天我们来讲讲如何用Python的一个优秀的第三方包来调用RESTfulAPI,实现一些基本的操作。

顺便打个广告,10.12会在网上有一个分享,讲讲我看到的国外的netdevops网工的一些有意思的东西(人+工具+思路),抛砖引玉,会有一些现场coding演示,大家有兴趣,可以来听听ppt还没写,发完这个我得抽时间再写写PPT。。。

大家可以加工作人员好友进群听听。请备注“直播”

1bfebb579b6eaacee7dc9ad79e64fd43.png

requests

我们今天用到了优秀的第三方包是requests,这是一个基于python内置的http请求包封装的一个程序,它能让我们调用http请求更加的简单。

安装方法是 pip install requests

我们先来看看requests的官方简介,透漏着一股子傲娇

Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。

警告:非专业使用其他 HTTP 库会导致危险的副作用,包括:安全缺陷症、冗余代码症、重新发明轮子症、啃文档症、抑郁、头疼、甚至死亡。

我们来比对一下,用了requests 和没用requests的区别吧。

没有用的是:

import urllib2

gh_url = 'https://api.github.com'

req = urllib2.Request(gh_url)

password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_manager.add_password(None, gh_url, 'user', 'pass')

auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
opener = urllib2.build_opener(auth_manager)

urllib2.install_opener(opener)

handler = urllib2.urlopen(req)

print handler.getcode()
print handler.headers.getheader('content-type')

# ------
# 200
# 'application/json'

以上是官方的,但是是py2的一个老版本,py3中有改变,但调用过程基本差不多。

用了的是:

import requests

r = requests.get('https://api.github.com', auth=('user', 'pass'))

print r.status_code
print r.headers['content-type']

# ------
# 200
# 'application/json'

高下立判。

Requests 允许你发送纯天然,植物饲养的 HTTP/1.1 请求,无需手工劳动。你不需要手动为 URL 添加查询字串,也不需要对 POST 数据进行表单编码。Keep-alive 和 HTTP 连接池的功能是 100% 自动化的,一切动力都来自于根植在 Requests 内部的 urllib3。

这个也是官方介绍,我所关注的是:

  1. 做一些get查询时,我们关注于数据即可,不用过分关注格式(比如我们需要编码汉字,特殊字符,分隔开多个查询变量等)
  2. 做post等数据的时候,不需要做一些表单编码或者json的个生命,它会自动在header和数据层面帮我们处理

这就是requests ,官方文档地址如下:https://requests.readthedocs.io/zh_CN/latest/

补充 同时对于认证,也有很方便的使用,也可以自己继承一些类,实现各类认证方式的扩展支持。

requests初窥

requests发送各种请求,直接在requests后面调用get post或者其他方法名称即可,他们每个都是一个方法,第一个参数是url,其他的可能略有差异,我们后面慢慢讲明显简单给大家展示一下。

发送get请求

使用 Requests 发送网络请求非常简单。

一开始要导入 Requests 模块:

>>> import requests

然后,尝试获取某个网页。本例子中,我们来获取 Github 的公共时间线:

>>> r = requests.get('https://api.github.com/events')

现在,我们有一个名为 rResponse 对象。我们可以从这个对象中获取所有我们想要的信息。

Requests 简便的 API 意味着所有 HTTP 请求类型都是显而易见的。例如,你可以这样发送一个 HTTP POST 请求:

>>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})

漂亮,对吧?那么其他 HTTP 请求类型:PUT,DELETE,HEAD 以及 OPTIONS 又是如何的呢?都是一样的简单:

>>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})
>>> r = requests.delete('http://httpbin.org/delete')
>>> r = requests.head('http://httpbin.org/get')
>>> r = requests.options('http://httpbin.org/get')

都很不错吧,但这也仅是 Requests 的冰山一角呢。

get中传递 URL 参数

你也许经常想为 URL 的查询字符串(query string)传递某种数据。如果你是手工构建 URL,那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。例如, httpbin.org/get?key=val。Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数。举例来说,如果你想传递 key1=value1key2=value2httpbin.org/get ,那么你可以使用如下代码:

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get("http://httpbin.org/get", params=payload)

通过打印输出该 URL,你能看到 URL 已被正确编码:

汉字、长长的有空格标点等的字符串都不在话下

>>> print(r.url)
# http://httpbin.org/get?key2=value2&key1=value1

注意字典里值为 None 的键都不会被添加到 URL 的查询字符串里。

你还可以将一个列表作为值传入:

>>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}

>>> r = requests.get('http://httpbin.org/get', params=payload)
>>> print(r.url)
# http://httpbin.org/get?key1=value1&key2=value2&key2=value3

这点大家一定要留意,http的get方法是可以处理列表(数组)的,key值重复即可,但是相对应的,后台需要有对应的处理能力,如果后台代码写的不好,有可能只取出一个值。

简单看响应内容

我们能读取服务器响应的内容。再次以 GitHub 时间线为例:

>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r.text
u'[{"repository":{"open_issues":0,"url":"https://github.com/...

前提是返回的是字符串,我们可以用text。

大家要理解,http请求来回传的都是字节流,header肯定是可以解析成k,v的键值对,但是body可不一定了,我们的例子返回的是文本,可以解析,但是有时候返回的是文件或者图片,这个时候需要对字节流进行处理才可以,我们下节再讲。

稍微复杂的POST请求

普通表单

通常,你想要发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个,只需简单地传递一个字典给 data 参数。你的数据字典在发出请求时会自动编码为表单形式:

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post("http://httpbin.org/post", data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}

你还可以为 data 参数传入一个元组列表。在表单中多个元素使用同一 key 的时候,这种方式尤其有效:

>>> payload = (('key1', 'value1'), ('key1', 'value2'))
>>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
"form": {
"key1": [
"value1",
"value2"
]
},
...
}

以上,requests会在header的content-type里标明是x-www-form-urlencoded,代表这是一个表单这些都是隐式的,大家看不到的。

json格式数据post

很多时候你想要发送的数据并非编码为表单形式的。包括现在很多api基本都是基于json的,这段希望大家仔细看看。

我们想用json传送数据,那我们需要编码数据为json格式的字符串:

>>> import json

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, data=json.dumps(payload))

但是这段不是那么完善,有几点我想说明一下

  1. json本质是特殊格式的字符串
  2. 你传 了一个json格式的字符串过去,但是有的服务器,或者api会检查你的header里是否声明了这是一个json(这其实是一个严谨的做法)
  3. 如果服务器会检查header我们需要指定header里的content-type为json。

此处除了可以自行对 dict 进行编码,你还可以使用 json 参数直接传递,然后它就会被自动编码。这时候注意,requests会自动的处理header,我们无需额外声明。这点就是requests强大的地方,会默默帮我们做很多事情,用它的话说是给人用的。

强烈建议大家记住这招,如果传的数据是json,尽量不要用data=XXX,而是使用json=xxx

>>> import requests

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)

以上就是今天所讲,大家有兴趣可以试试。

欢迎大家继续关注、点赞、分享、喜欢、收藏、订阅,推荐给你身边的网工!

同名知乎专栏和微信公众号:NetDevOps加油站,欢迎你的加入!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值