通过百度 OCR 工具识别 rap2 登录中的验证码,从而实现登录~那我们今天来实战解析 rap2 的接口数据,生成我们所需要的接口数据

实践上手

文档分析

1、我们先通过 F12 看看哪个接口是我们需要的?对~就是你了!

 

2、将接口数据复制到https://www.json.cn/,我们来看看接口数据结构,看看有哪些信息是需要的

 

 

3、通过分析 properties 中的数据,发现 pos=1 为请求头,pos=2 为路径参数,pos=3 为 body 参数,name 为字段名,value 为字段值,parentId=1,没有父节点;parentId!=-1,为父节点

 

 

代码解析

上一期中,有小伙伴反馈说,可以输入 cookies 不?那这次优化一下吧~

实现 rap2 登录并获取数据

@classmethod
def rap_data(cls, id, cookies = None):
"""
获取接口文档数据
:param id: 接口文档id
:param cookies: 非必填,登录的cookies
:return: 返回json数据
"""
params = {"id": id}
if cookies:
try:
cls.cookies = dict([i.split("=", 1) for i in cookies.split("; ")])
except Exception as e:
raise Exception('cookies格式不对,请重新输入!')
try:
res = requests.get(url=UrlConfig.RAP_PROJRCT_URL, params=params, cookies=cls.cookies).json()
except Exception as e:
raise Exception('cookies过期了,请重新输入!')
return res
else:
login_result = False
#判断是否登录成功
while not login_result:
login_result = Rap2Data.rap_login()
res = requests.get(url=UrlConfig.RAP_PROJRCT_URL, params=params, cookies=cls.cookies).json()
return res

解析关键代码展示:执行主入口

class Rap2Parse(object):

    @classmethod
def api_data(cls, id, cookies=None, module=None):
json_obj = Rap2Data.rap_data(id, cookies)
errMsg = json_obj.get("errMsg")
#获取报错信息,将其抛出(权限不足、不存在接口文档,接口都会返回errMsg)
if errMsg:
errMsg = errMsg + f"请将接口文档授权给{Account.RAP['email']}!"
raise Exception(errMsg)
if module is None:
#模块名不传的话,默认获取所有模块数据
json_list = json_obj['data']['modules']
else:
#模块名传入,获取对应的模块数据
json_list = jsonpath(json_obj, f"$.data.modules[?(@.name=='{module}')]")
#校验传入的模块名是否存在
if not json_list:
raise Exception(f"{module}模块名不存在")
# 接口文档标题名,作为后续的文件名
file_name = json_obj.get('data').get('name')
#对标题名特殊处理
special_str = r"[\/\\\:\*\?\"\<\>\|]"
file_name = re.sub(special_str, "-", file_name)
data = []
#遍历模块数据
for i in json_list:
modules_data = {}
#模块名
modules_data['modules'] = i['name']
#模块描述
modules_data['description'] = i['description']
interfaces = []
#遍历interfaces接口数据
for i, dto in enumerate(i['interfaces']):
cases_data = {}
#接口id
cases_data['api_id'] = i + 1
#接口名
cases_data['title'] = dto['name']
#接口描述
cases_data['description'] = dto['description']
#接口路径
cases_data['url'] = dto['url']
#接口请求方法
cases_data['method'] = dto['method']
#获取接口的入参和出参
properties_list = jsonpath(dto['properties'], f"$.[?(@.scope=='request')]")
#接口请求头数据
cases_data['headerData'] = cls.parent_data(properties_list)[2]
#接口query参数
cases_data['queryData'] = cls.parent_data(properties_list)[1]
#接口body参数
cases_data['data'] = cls.parent_data(properties_list)[0]
interfaces.append(cases_data)
modules_data['cases_data'] = interfaces
data.append(modules_data)
return data, file_name

组装参数

@classmethod
def join_data(cls, json_data, properties, name, type, value, parentId, api_id):
"""
组装参数
:param json_data: 字典值(存数据用)
:param properties: 接口的入参和出参数据
:param name: 接口名
:param type: 字段类型
:param value: 字段值
:param parentId: 父id
:param api_id: 所有的参数id
:return: json_data
"""
#特殊字符替换
name = name.replace(".","")
#没有父id,直接塞进json_data
if parentId == -1:
v = cls.change_value(type, value)
json_data[name] = v
#有父id且父id在api_id中
elif parentId != -1 and parentId in api_id:
#根据父id获取父id的数据
parent_dto = jsonpath(properties, f"$.[?(@.id=={parentId})]")
if not parent_dto:
raise Exception("接口文档维护有误")
parent_dto = parent_dto[0]
#如果父的类型为数组
if parent_dto['type'] == 'Array':
#找到父的key
parent_array = cls.search_value(json_data, parent_dto['name'])
v = cls.change_value(type, value)
#将子数据挂载在父下面
parent_array[0][name] = v
# 如果父的类型为对象
elif parent_dto['type'] == 'Object':
# 找到父的key
parent_object = cls.search_value(json_data, parent_dto['name'])
v = cls.change_value(type, value)
# 将子数据挂载在父下面
parent_object[name] = v
else:
raise Exception("父数据类型不支持")
else:
pass
# raise Exception("父数据类型不支持")
return json_data

递归找对应的 key 数据

@classmethod
def search_value(cls, data, key):
"""
递归找到所在key的数据
:param data: 数据
:param key: 需要找的key
:return:
"""
key = key.replace(".", "")
json_data = JsonSearch(object=data)
path = json_data.search_first_path(key)
path_str = cls.path_str(path)
value = jsonpath(data, path_str)[0]
return value

解析后数据展示

 

项目地址:https://github.com/JokerChat/ApiDocParse

后续扩展

  • 将数据生成 Excel 格式的接口自动化用例
  • 将数据生成 yaml 格式接口自动化用例
  • 将数据生成生成 jmeter 脚本 (jmx)
  • 基于上述功能,做成前端页面,供其他人使用

最新文章

  1. JavaWeb chapter6 对象作用域
  2. Daily Scrum 12.5
  3. 边工作边刷题:70天一遍leetcode: day 74
  4. UI之UItableView重用机制的性能问题
  5. Android Loader详解一:概述
  6. Windows 7硬盘安装CentOS 6.4 双系统 (WIN7硬盘安装Linux(Fedora 16,CentOS 6.2,Ubuntu 12.04))
  7. “百度杯”CTF比赛 九月场_再见CMS(齐博cms)
  8. 单例模式--java代码实现
  9. python实现常见排序算法
  10. python,os.path简单用法
  11. mysql常用赋权命令
  12. 前缀和与差分之IncDec sequence
  13. Spring Boot的@SpringBootApplication无法引入的问题
  14. C#深入解析委托——C#中为什么要引入委托
  15. Handler 、 Looper 、Message异步消息处理线程机制( hander消息机制原理)
  16. 跨平台开发 -- C# 使用 C/C++ 生成的动态链接库
  17. php反射方法信息
  18. 20 个具有惊艳效果的 jQuery 图像缩放插件
  19. iOS&#39;s GCD Note
  20. 定义JQuery插件

热门文章

  1. CF1458D Flip and Reverse[题解]
  2. python使用笔记002
  3. C语言:赋值语句
  4. C控制台程序 GUI程序
  5. VS Code 下载安装并设置中文面板显示
  6. docker容器技术基础之联合文件系统OverlayFS
  7. Linux CentOS 7 在Apache服务器上安装SSL证书
  8. Word中的代码怎样语法高亮
  9. noip模拟27[妹子图&#183;腿&#183;腰](fengwu半仙的妹子们)
  10. Skywalking-04:扩展Metric监控信息