python接口自动化(1)requests模块
requests模块
requests模块支持的请求方式
1 requests.get(‘https://github.com/timeline.json’) # GET请求
2 requests.post(“http://httpbin.org/post”) # POST请求
3 requests.put(“http://httpbin.org/put”) # PUT请求
4 requests.delete(“http://httpbin.org/delete”) # DELETE请求
5 requests.head(“http://httpbin.org/get”) # HEAD请求
6 requests.options(“http://httpbin.org/get” ) # OPTIONS请求
定制get/post请求头
注意:
get
请求时,url
中的请求参数(即queryString
)使用params
来设定,一般来说,直接在url中填写就行了,不用单独用一个字典来写- 只有
post
请求时,才有data
,data
对应的是请求body
- 发送请求时,参数里面不能同时存在
params
和data
,否则报错,所以一般建议在url
的参数就写在url
就好了 verify
是使用https
的时候才用到。
请求的返回内容
r.status_code #响应状态码
r.content #字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩
r.headers #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None
r.json() #Requests中内置的JSON解码器 ,json转成python的字典了
r.url # 获取url
r.encoding # 编码格式
r.cookies # 获取cookie
r.raw #返回原始响应体
r.text #字符串方式的响应体,会自动根据响应头部的字符编码进行解码
r.raise_for_status() #失败请求(非200响应)抛出异常
注意:
- 响应内容必须是
json
格式的,才能用r.json()
,否则会报错! - 有些响应内容是
gzip
压缩的,text
只能打印文本内容,用content
是二进制流,一般获取返回值内容,推荐用content
r.content
获取的响应内容是字节形式的,如果要将字节内容转为字符串,有以下两种方法:- 使用
str()
方法:str(login_r.content,encoding='utf-8')
- 使用
bytes.decode()
方法:bytes.decode(login_r.content)
- 使用
SSL证书解决方法
官方文档:https://2.python-requests.org/en/master/user/advanced/#verification
第一种方法:设定证书路径
第二种方法:忽略证书确认
json请求参数
当post
请求的body
为json
格式时,有两种方法传json
参数:
第一种:传json
参数(自动转json
了)
第二种:传data
参数(需json
转换)
奇怪实例:实现下面图中的请求,可以看到请求body
中是json
格式的,而且有些值为null
,python
中只有None
,没有null
,所以会报错。解决办法是:字符串转为字典或者null
改为None
import requests
import json
s=requests.Session()
login_url = 'http://192.168.239.135:8080/recruit.students/login/in'
login_payload = {
"account": "admin",
"pwd": "660B8D2D5359FF6F94F8D3345698F88C"
}
login_r=s.post(url=login_url,data=login_payload)
print(login_r.text)
# 解决办法1:字符串转为字典:
settime_url='http://192.168.239.135:8080/recruit.students/school/manage/setStudentRecruitTime'
settime_payload=json.loads('[{"id":"280","recruitStartTime":null,"recruitEndTime":null,"isStudentRecruitTime":"0"}]')
settime_r=s.post(url=settime_url,json=settime_payload)
print(settime_r.text)
# 解决办法2:null改为None
settime_url='http://192.168.239.135:8080/recruit.students/school/manage/setStudentRecruitTime'
settime_payload=[{"id":"280","recruitStartTime":None,"recruitEndTime":None,"isStudentRecruitTime":"0"}]
settime_r=s.post(url=settime_url,json=settime_payload)
print(settime_r.text)
url编码与解码
对url
中的中文进行编码:
对url
中的中文进行解码:
xiaoqiang实例
访问xiaoqiang
系统的流水式代码:
import requests
import time
s=requests.Session()
login_url = 'http://192.168.239.128/xiaoqiangshop/user.php'
login_body = {
'username': 'xiaoqiang1',
'password': '123123',
'act': 'act_login',
'back_act': 'user.php',
'submit': ''
}
login_r=s.post(url=login_url,data=login_body)
print(login_r.text)
#===========================================
search_url='http://192.168.239.128/xiaoqiangshop/goods.php'
search_params={'id':'134'}
search_r=s.get(url=search_url,params=search_params)
print(login_r.text)
#============================================
addToCar_url='http://192.168.239.128/xiaoqiangshop/flow.php'
addToCar_params={'step':'add_to_cart'}
addToCar_body={'goods':'{"quick":1,"spec":[],"goods_id":134,"number":"1","parent":0}'}
addToCar_r=s.post(url=addToCar_url,params=addToCar_params,data=addToCar_body)
print(addToCar_r.text)
#=================================================
checkOut_url='http://192.168.239.128/xiaoqiangshop/flow.php'
checkOut_params={'step':'checkout'}
checkOut_r=s.get(url=checkOut_url,params=checkOut_params)
print(checkOut_r.text)
#===================================================
done_url='http://192.168.239.128/xiaoqiangshop/flow.php?step=done'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
'Content-Type':'application/x-www-form-urlencoded'
}
done_body={
'shipping':'1',
'payment':'1',
'bonus':'0',
'bonus_sn':'',
'postscript':'',
'how_oos':'0',
'x':'29',
'y':'14',
'step':'done'
}
done_r=s.post(url=done_url,data=done_body,headers=headers)
print(done_r.text)
访问xiaoqiang
的封装后的代码:
import requests
import time
class xiaoQiang:
s=requests.Session()
def __init__(self):
pass
def xq_login(self,username,password):
login_url = 'http://192.168.239.128/xiaoqiangshop/user.php'
login_body = {
'username': username,
'password': password,
'act': 'act_login',
'back_act': 'user.php',
'submit': ''
}
login_r = self.s.post(url=login_url, data=login_body)
return login_r
def xq_search(self):
search_url = 'http://192.168.239.128/xiaoqiangshop/goods.php'
search_params = {'id': '134'}
search_r = self.s.get(url=search_url, params=search_params)
return search_r
def xq_addToCar(self):
addToCar_url = 'http://192.168.239.128/xiaoqiangshop/flow.php'
addToCar_params = {'step': 'add_to_cart'}
addToCar_body = {'goods': '{"quick":1,"spec":[],"goods_id":134,"number":"1","parent":0}'}
addToCar_r = self.s.post(url=addToCar_url, params=addToCar_params, data=addToCar_body)
return addToCar_r
def xq_checkout(self):
checkOut_url = 'http://192.168.239.128/xiaoqiangshop/flow.php'
checkOut_params = {'step': 'checkout'}
checkOut_r = self.s.get(url=checkOut_url, params=checkOut_params)
return checkOut_r
def xq_done(self):
done_url = 'http://192.168.239.128/xiaoqiangshop/flow.php?step=done'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded'
}
done_body = {
'shipping': '1',
'payment': '1',
'bonus': '0',
'bonus_sn': '',
'postscript': '',
'how_oos': '0',
'x': '29',
'y': '14',
'step': 'done'
}
done_r = self.s.post(url=done_url, data=done_body, headers=headers)
return done_r
if __name__=='__main__':
xq=xiaoQiang()
login_r=xq.xq_login('xiaoqiang1',123123)
search_r=xq.xq_search()
addToCar_r=xq.xq_addToCar()
checkout_r=xq.xq_checkout()
done_r=xq.xq_done()
招生系统实例
关键步骤:从新建学校一步,使用正则表达式提取禁用学校一步要用到的信息(相当于jmeter
中的参数关联):
访问招生系统的流水式代码:
import requests
import time
import random
import re
s=requests.Session()
# ===============登录==========================
login_url='http://192.168.239.135:8080/recruit.students/login/in?account=admin&pwd=660B8D2D5359FF6F94F8D3345698F88C'
login_r=s.get(url=login_url)
print(login_r)
#===============新建学校========================
addSchool_url='http://192.168.239.135:8080/recruit.students/school/manage/addSchoolInfo'
addSchool_data={
'schoolName':'{}'.format("".join(random.sample("我双开的发送垃圾分类卡积分",4))),
'listSchoolType%5B0%5D.id':'2',
'canRecruit':'1',
'remark':''
}
addSchool_r=s.post(url=addSchool_url,data=addSchool_data)
print(addSchool_r.text)
type(addSchool_r.text)
#================禁用学校=======================
disableSchool_url='http://192.168.239.135:8080/recruit.students/school/manage/enableOrDisableSchool'
headers={
'Content-Type': 'application/json'
}
id=re.search(r'"laccount":(\d+),"sta',addSchool_r.text).group(1)
schoolId=re.search(r'data":{"id":(\d*),"schoo',addSchool_r.text).group(1)
# id=re.findall(r'"laccount":(.*?),"sta',addSchool_r.text)
disableSchool_data=[{"id":"{}".format(id),"disable":0,"schoolId":"{}".format(schoolId)}]
disableSchool_r=s.post(url=disableSchool_url,json=disableSchool_data,headers=headers)
print(disableSchool_r.text)
封装后的代码:
import requests
import time
import random
import re
class recruit:
s=requests.Session()
def __init__(self):
pass
def login(self):
login_url = 'http://192.168.239.135:8080/recruit.students/login/in?account=admin&pwd=660B8D2D5359FF6F94F8D3345698F88C'
login_r = self.s.get(url=login_url)
return login_r
def addSchool(self):
addSchool_url = 'http://192.168.239.135:8080/recruit.students/school/manage/addSchoolInfo'
addSchool_data = {
'schoolName': '{}'.format("".join(random.sample("我双开的发送垃圾分类卡积分", 4))),
'listSchoolType%5B0%5D.id': '2',
'canRecruit': '1',
'remark': ''
}
addSchool_r = self.s.post(url=addSchool_url, data=addSchool_data)
return addSchool_r
def disableOrEnable(self,addSchool_r):
disableSchool_url = 'http://192.168.239.135:8080/recruit.students/school/manage/enableOrDisableSchool'
headers = {
'Content-Type': 'application/json'
}
id = re.search(r'"laccount":(\d+),"sta', addSchool_r.text).group(1)
schoolId = re.search(r'data":{"id":(\d*),"schoo', addSchool_r.text).group(1)
# id=re.findall(r'"laccount":(.*?),"sta',addSchool_r.text)
disableSchool_data = [{"id": "{}".format(id), "disable": 0, "schoolId": "{}".format(schoolId)}]
disableSchool_r = self.s.post(url=disableSchool_url, json=disableSchool_data, headers=headers)
return disableSchool_r
if __name__=='__main__':
rs=recruit()
login_r=rs.login()
addSchool_r=rs.addSchool()
de_r=rs.disableOrEnable(addSchool_r=addSchool_r)
用python写测试的建议
1、接口与测试的分离
接口写在一个.py
文件(模块)
测试用例写在一个.py
文件(模块)