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请求头

image-20200922163016598

注意:

  • get请求时,url中的请求参数(即queryString)使用params来设定,一般来说,直接在url中填写就行了,不用单独用一个字典来写
  • 只有post请求时,才有datadata对应的是请求body
  • 发送请求时,参数里面不能同时存在paramsdata,否则报错,所以一般建议在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响应)抛出异常

注意:

  1. 响应内容必须是json格式的,才能用r.json(),否则会报错!
  2. 有些响应内容是gzip压缩的,text只能打印文本内容,用content是二进制流,一般获取返回值内容,推荐用content
  3. r.content获取的响应内容是字节形式的,如果要将字节内容转为字符串,有以下两种方法
    1. 使用str()方法:str(login_r.content,encoding='utf-8')
    2. 使用bytes.decode()方法:bytes.decode(login_r.content)

SSL证书解决方法

官方文档:https://2.python-requests.org/en/master/user/advanced/#verification

第一种方法:设定证书路径

image-20200923101459897

第二种方法:忽略证书确认

image-20200923101629814

json请求参数

post请求的bodyjson格式时,有两种方法传json参数:

第一种:传json参数(自动转json了)

image-20200923103150358

第二种:传data参数(需json转换)

image-20200923103225041

奇怪实例:实现下面图中的请求,可以看到请求body中是json格式的,而且有些值为nullpython中只有None,没有null,所以会报错。解决办法是:字符串转为字典或者null改为None

image-20200924171529455

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中的中文进行编码:

image-20200923105012245

url中的中文进行解码:

image-20200923105806680

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中的参数关联):

image-20200923110012327

访问招生系统的流水式代码:

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文件(模块)

image-20200924154509349

测试用例写在一个.py文件(模块)

image-20200924154712399

posted @ 2020-08-31 00:31  Whatever_It_Takes  阅读(251)  评论(0编辑  收藏  举报