requests庫官方使用手冊地址:http://www.python-requests.org/en/master/;中文使用手冊地址:http://cn.python-requests.org/zh_CN/latest/;html
requests庫做者Kenneth Reitz我的主頁:https://www.kennethreitz.org/;python
requests庫github地址:https://github.com/requests/requests;git
requests庫下載方法:pip install requestsgithub
學習目的:Python+requests庫實現接口自動化測試;json
requests庫做者Kenneth Reitz建立的server端:http://httpbin.org/;能夠學習時使用。小程序
python自帶的接口測試的庫urllib、urllib二、urllib3,這三個庫不是進階關係,是彼此獨立的。requests庫使用了urllib3(屢次請求重複使用一個socket,消耗更少的資源)。api
1.使用urllib、urllib2實現的一個小程序:瀏覽器
# -*- coding: utf-8 -*-
import urllib
import urllib2 #引入urllib、urllib2庫
URL_IP = 'http://httpbin.org/ip'
URL_GET = 'http://httpbin.org/get'
def use_simple_urllib2():
response = urllib2.urlopen(URL_IP) #urlopen() 訪問url的方法
print '>>>>Response Headers:'
print response.info() #info() 打印headers的方法
print '>>>>Response body:'
print ''.join([line for line in response.readlines()]) #join() 將response body中的元素以"鏈接生成一個新的字符串 str = "-"; seq = ("a", "b", "c"); print str.join( seq ); 結果:a-b-c安全
def use_params_urllib2():
#構建請求參數服務器
params = urllib.urlencode({'param1': 'hello', 'param2': 'world'}) #urlencode() 將參數進行url編碼
#發送請求
response = urllib2.urlopen('?'.join([URL_GET, '%s']) % params)
#處理響應
print '>>>>Response Headers:'
print response.info()
print '>>>>Status Code:'
print response.getcode() #getcode()獲取status code的方法
print '>>>>Request body:'
print ''.join([line for line in response.readlines()])
if __name__ == '__main__':
print '>>>Use simple urllib2:'
use_simple_urllib2()
print ''
print '>>>Use params urllib2:'
use_params_urllib2()
服務器返回的數據:
C:\Python27\python.exe C:/Users/lxz/Desktop/study/AndroidAppshizhandaima/HttpApi/jiekouceshi.py
>>>Use simple urllib2:
>>>>Response Headers:
Connection: close #能夠看到,一次請求後connection的狀態是close,說明urllib庫每次都要從新打開一個socket
Server: meinheld/0.6.1
Date: Fri, 18 Aug 2017 06:25:44 GMT
Content-Type: application/json
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Powered-By: Flask
X-Processed-Time: 0.000429153442383
Content-Length: 32
Via: 1.1 vegur
>>>>Response body:
{
"origin": "39.109.125.70"
}
>>>Use params urllib2:
>>>>Response Headers:
Connection: close
Server: meinheld/0.6.1
Date: Fri, 18 Aug 2017 06:25:44 GMT
Content-Type: application/json
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Powered-By: Flask
X-Processed-Time: 0.000815868377686
Content-Length: 309
Via: 1.1 vegur
>>>>Status Code:
200
>>>>Request body:
{
"args": {
"param1": "hello",
"param2": "world"
},
"headers": {
"Accept-Encoding": "identity",
"Connection": "close",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/2.7"
},
"origin": "39.109.125.70",
"url": "http://httpbin.org/get?param2=world¶m1=hello"
}
2.使用requests實現的一個小程序:
#coding=utf-8
import requests #引入requests庫
URL_IP = 'http://httpbin.org/ip'
URL_GET = 'http://httpbin.org/get'
def use_simple_requests():
response = requests.get(URL_IP) #以get方法訪問url
print '>>>>Response Headers:'
print response.headers # .headers 獲取headers
print '>>>>Response body:'
print response.text # .text 獲取值
def use_params_requests():
params = {'param1': 'hello', 'param2': 'world'} #參數直接以字典的形式賦值,不須要編碼
#發送請求
response = requests.get(URL_GET, params=params) #get方法會自動鏈接url和參數
#處理響應
print '>>>>Response Headers:'
print response.headers
print '>>>>Status Code:'
print response.status_code # .status_code 獲取status_code方法
print '>>>>Reason:'
print response.reason # .reason 獲取訪問接口結果方法
print '>>>>Request body:'
print response.text # .text 獲取值
if __name__ == '__main__':
print '>>>Use simple requests:'
use_simple_requests()
print ''
print '>>>Use params requests:'
use_params_requests()
服務器返回的數據:
>>>Use simple requests:
>>>>Response Headers:
{'Content-Length': '34', 'X-Processed-Time': '0.000436067581177', 'X-Powered-By': 'Flask', 'Server': 'meinheld/0.6.1', 'Connection': 'keep-alive', 'Via': '1.1 vegur', 'Access-Control-Allow-Credentials': 'true', 'Date': 'Sat, 19 Aug 2017 08:12:17 GMT', 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'}
>>>>Response body:
{
"origin": "111.204.108.132"
}
>>>Use params requests:
>>>>Response Headers:
{'Content-Length': '343', 'X-Processed-Time': '0.000698089599609', 'X-Powered-By': 'Flask', 'Server': 'meinheld/0.6.1', 'Connection': 'keep-alive', 'Via': '1.1 vegur', 'Access-Control-Allow-Credentials': 'true', 'Date': 'Sat, 19 Aug 2017 08:12:18 GMT', 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'}
#能夠看到使用requests庫,connection的狀態是keep-alive,這就說明了屢次請求重複使用一個socket,因此相比urllib庫,requests庫會消耗更少的資源
>>>>Status Code:
200
>>>>Reason:
OK
>>>>Request body:
{
"args": {
"param1": "hello",
"param2": "world"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.3"
},
"origin": "111.204.108.132",
"url": "http://httpbin.org/get?param2=world¶m1=hello"
}
3.發送請求
請求方法:
使用requests庫發送請求的方法:requests.[method](url)
PATCH:更新資源;經過提交json數據的方式實現,相比較PUT,PATCH更輕量級。
github上公共API的使用方法地址:https://developer.github.com/v3/
使用時調用URL:https://api.github.com #能夠用來平常學習使用
下面的演示用代碼都會用到以上兩個域名。
3.1,獲取用戶名方法 https://developer.github.com/v3/users
其中https://api.github.com是根域名,/users/username是endpoint。
github官網上返回數據的樣例:
實現代碼:
# -*- coding: utf-8 -*-
import json
import requests
URL = 'https://api.github.com'
def build_uri(endpoint):
return '/'.join([URL, endpoint])
def better_print(json_str):
return json.dumps(json.loads(json_str), indent=4)
def request_method():
response = requests.get(build_uri('users/caolanmiao'))
print better_print(response.text)
if __name__ == '__main__':
request_method()
返回的數據:
{
"public_repos": 0,
"site_admin": false,
"subscriptions_url": "https://api.github.com/users/caolanmiao/subscriptions",
"gravatar_id": "",
"hireable": null,
"id": 22490616,
"followers_url": "https://api.github.com/users/caolanmiao/followers",
"following_url": "https://api.github.com/users/caolanmiao/following{/other_user}",
"blog": "",
"followers": 0,
"location": "Pecking",
"type": "User",
"email": null,
"bio": "Software QA Engineer",
"gists_url": "https://api.github.com/users/caolanmiao/gists{/gist_id}",
"company": null,
"events_url": "https://api.github.com/users/caolanmiao/events{/privacy}",
"html_url": "https://github.com/caolanmiao",
"updated_at": "2017-08-19T09:27:39Z",
"received_events_url": "https://api.github.com/users/caolanmiao/received_events",
"starred_url": "https://api.github.com/users/caolanmiao/starred{/owner}{/repo}",
"public_gists": 0,
"name": "Yannan.Jia",
"organizations_url": "https://api.github.com/users/caolanmiao/orgs",
"url": "https://api.github.com/users/caolanmiao",
"created_at": "2016-09-28T06:00:27Z",
"avatar_url": "https://avatars0.githubusercontent.com/u/22490616?v=4",
"repos_url": "https://api.github.com/users/caolanmiao/repos",
"following": 1,
"login": "caolanmiao"
}
返回的數據信息中就是我本身的github帳號,說明此次請求成功了。
注意:對於github而言,傳入參數auth=('用戶名','密碼'),既能夠完成認證。
訪問user/emails API,修改上述代碼的如下部分,增長auth參數,完成認證
response = requests.get(build_uri('user/emails'),auth=('caolanmiao','########'))
返回數據:
[{"email":"jia#####@outlook.com","primary":true,"verified":true,"visibility":"public"}]
[
{
"verified": true,
"email": "jia#####@outlook.com",
"visibility": "public",
"primary": true
}
]
符合API使用說明。
3.2,帶參數的請求
get方式:這種參數直接拼接在url後面的參數提交方式的優勢是:信息傳遞/頁面到頁面的跳轉方便;缺點:明文顯示,安全性差、瀏覽器對url的長度有限制。
post方式:安全性強,能夠傳遞大量參數。
1.get方式實現參數傳遞,測試用API地址:https://developer.github.com/v3/users
since參數會過濾掉在它以前的users(好比since爲11,那麼只顯示11以後的users)
實現代碼:
# -*- coding: utf-8 -*-
import json
import requests
from requests import exceptions
URL = 'https://api.github.com'
def build_uri(endpoint):
return '/'.join([URL, endpoint])
def better_print(json_str):
return json.dumps(json.loads(json_str), indent=4)
def params_request():
response = requests.get(build_uri('users'), params={'since': 11})
print better_print(response.text)
print response.request.headers
print response.url
if __name__ == '__main__':
params_request()
2.post、patch方式實現參數傳遞,測試用API地址:https://developer.github.com/v3/users/emails/
實現代碼:
def json_request():
response = requests.patch(build_uri('user'), auth=('caolanmiao', '########'), json={'name': 'Yannan.Jia', 'email': 'helloworld1@ceshi.com'})
response = requests.post(build_uri('user/emails'), auth=('caolanmiao', '########'), json=['helloworld2@ceshi.com'])
print better_print(response.text)
print response.request.headers
print response.request.body
print response.status_code
經過Patch方法,修更名稱和郵箱;經過Post增長郵箱;