标题
雪球app抓包与mock实战
课程价值
- 掌握 mock 使用场景,基本 mock 原理
- 掌握抓包工具charles、mitmproxy的使用和应用场景
大纲
- mock基本原理
- charles map local实战回顾
- mitmproxy 安装
- mitmproxy 实战练习
时长
90 分钟
内容
mock原理与使用场景
官方文档
原理
-
使用场景
- 前后端分离,被测对象是前端
- 模拟第三方服务的响应数据,达到测试目的
- 解耦硬件设备,模拟硬件的返回信息
-
使用条件
- 了解响应的数据格式
- 服务与mock服务的通讯协议保持一致
charles_map_local回顾
mitmproxy原理
mitmproxy 安装
- mac环境
brew install mitmproxy
- windows 环境
- 在 windows 中,以管理员身份运行 cmd 或 power shell
- 命令:
pip install pipx
pipx install mitmproxy
或者直接使用 pip install mitmproxy
- 安装之后需要配置环境变量:安装成功的提示中会给出需要配置的目录,将其配置到path环境变量中重启cmd即可
检查是否安装成功
mitmdump --version
证书配置
- 在浏览器连接代理
- 输入
mitmdump
开启mitmproxy 的服务 - 进入mitm.it 页面
- 选择对应的系统下载、安装
手机
-
进入手机完成网络配置
-
输入
mitmdump
开启mitmproxy 的服务 -
进入mitm.it 页面
-
选择对应的系统下载、安装
mitmproxy
- windows 不支持只有mac支持
- 命令行交互工具
mitmweb
- 网页工具
mitmdump
- 查看命令信息
mitmdump --help
- 指定监听端口
mitmdump -p [监听端口]
- 指定关联的python脚本
mitmdump -s [指定脚本1路径]
rewrite
"""Send a reply from the proxy without sending any data to the remote server."""
import json
from mitmproxy import http
from mitmproxy import ctx
class Counter:
def __init__(self):
self.num = 0
def request(self, flow: http.HTTPFlow):
self.num = self.num + 1
ctx.log.info("We've seen %d flows" % self.num)
# 判断是否是想要的请求信息,通过url进行判断
def response(self, flow):
if "https://stock.xueqiu.com/v5/stock/batch/quote.json?_t=" \
in flow.request.pretty_url:
# 修改原始数据
# 获取的text 是str类型,如果要对数据进行操作,需要进行数据转换
data = json.loads(flow.response.text)
data["data"]["items"][0]["quote"]["name"] = "hogwarts"
data["data"]["items"][1]["quote"]["name"] = "hogwarts"
data["data"]["items"][2]["quote"]["name"] = "hogwarts"
flow.response.text = json.dumps(data)
# 赋值给响应信息
addons = [
Counter()
]
map_local
"""Send a reply from the proxy without sending any data to the remote server."""
import json
from mitmproxy import http
from mitmproxy import ctx
class Counter:
def __init__(self):
self.num = 0
def request(self, flow: http.HTTPFlow):
self.num = self.num + 1
ctx.log.info("We've seen %d flows" % self.num)
# 判断是否是想要的请求信息,通过url进行判断
def response(self, flow):
if "https://stock.xueqiu.com/v5/stock/batch/quote.json?_t=" \
in flow.request.pretty_url:
# 打开文件,读取文件数据,作为响应,给返回
with open("tmp2.json", encoding="utf-8") as f:
data = json.load(f)
flow.response.text = json.dumps(data)
addons = [
Counter()
]
递归批量处理数据信息
"""Send a reply from the proxy without sending any data to the remote server."""
import json
from mitmproxy import http
from mitmproxy import ctx
class Counter:
def __init__(self):
self.num = 0
def request(self, flow: http.HTTPFlow):
self.num = self.num + 1
# 判断是否是想要的请求信息,通过url进行判断
def response(self, flow: http.HTTPFlow):
if "https://stock.xueqiu.com/v5/stock/batch/quote.json?_t=" \
in flow.request.pretty_url:
# 打开文件,读取文件数据,作为响应,给返回
data = json.loads(flow.response.text)
flow.response.text = json.dumps(self.json_travel(data))
def json_travel(self, data):
# 判断传入的数据类型{"a": {"b":{"c":1}}}
if isinstance(data, dict):
# 遍历字典的数据
# 当字典格式,递归value值
for key, value in data.items():
data[key] = self.json_travel(value)
elif isinstance(data, list):
# 当数据类型 为 list 的时候, 添加到结构内,并继续递归遍历,
# 知道数据类型不为可迭代对象时
data = [self.json_travel(value) for value in data]
elif isinstance(data, bool):
data = data
elif isinstance(data, int) or isinstance(data, float):
data = data * 2
elif isinstance(data, str):
data = data
else:
data = data
return data
addons = [
Counter()
]
脱离命令行执行方式
if __name__ == '__main__':
sys.argv = [__file__, "-s", __file__]
#
# 官方要求必须主线程
mitmdump()