该博文是以友盟web端埋点为例,简单讲述了如何用代理工具获取埋点请求、解码并保存数据,这样就不用手工一个一个地去看请求和decodeURI ei参数了。

数据埋点
  1. 友盟统计点击事件埋点
    api介绍(https://open.cnzz.com/a/api/trackevent/)
  2. 纯手工测试做法
  1. 打开要测的网站,打开开发者工具,点击埋点的控件,如果已经做了埋点,应该能看到network页给https://ei.cnzz.com发送了一条get请求
    利用mitmproxy提高埋点测试效率_web端
  2. 点开这个请求,能看到有个ei参数
    利用mitmproxy提高埋点测试效率_数据_02
  3. 把ei参数的值拷贝下来,去控制台用chrome自带函数decodeURI解码成中文,再去跟需求文档对比
    利用mitmproxy提高埋点测试效率_数据_03
  1. 可以看到,由于中文和一些特殊字符被转码了,每次都要去控制台手动解码才能看到发送的数据,这样非常枯燥而且效率极低。
    所以想到在页面上点点点的时候用个代理工具获取发送给ei.cnzz.com的所有请求,并自动解码,这样总比一个一个去解效率高吧。当然你也可以进一步把点点点也用自动化取代,但是这个会比较耗时,所以这里就先没做了。
mitmproxy
  1. 什么是mitmproxy
    官网(​​https://www.mitmproxy.org/​​),是一个跟ClashX类似的代理工具,但是更灵活,能根据你的需求定制功能。包含mitmdump, mitmproxy, mitmweb等命令行和web端工具。
  2. 如何配置
    mac上直接 ​​brew install mitmproxy​​, ​​pip install mitmproxy​​, 按官网给的步骤配置好证书。
  3. 怎样使用
  1. 比如想记录我们发送了多少个请求,可以建一个python文件 'req_counter.py', 写上代码: import mitmproxy.http from mitmproxy import ctx class Counter: def __init__(self): self.num = 0 def request(self, flow: mitmproxy.http.HTTPFlow): self.num = self.num + 1 ctx.log.info("We've seen %d flows" % self.num) addons = [ Counter() ]
  2. 在terminal执行下面脚本,在8080端口启动一个mitmproxy
    ​PYTHONPATH=. mitmdump -p 8080 -s /Users/xxx/mitm/req_counter.py​
  3. 打开另一个terminal, 设置好chrome的代理启动chrome
    ​/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --proxy-server=127.0.0.1:8080 --ignore-certificate-errors​
  4. 此时打开任意网页,应该就能在mitmdump命令控制台看到输出了请求数
    利用mitmproxy提高埋点测试效率_chrome_04
编写脚本过滤和处理请求
  1. 直接用flow.request.query.get("ei") 获取 ei的值,比较简洁
    import mitmproxy.http import urllib import time addons = [ GetDataFromURL() ] class GetDataFromURL: def __init__(self): self.num = 0 def request(self, flow: mitmproxy.http.HTTPFlow): if flow.request.host != "ei.cnzz.com": # 忽略非ei.cnzz.com的请求 pass else: self.num += 1 ei = flow.request.query.get("ei") ei = urllib.parse.unquote(ei).split('|') res = [urllib.parse.unquote(e) for e in ei] # 再次解码每个子串 with open('maidian/maidian.txt', 'a+') as f: f.write(str(self.num) + ',' + time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + ',' + '-'.join(r for r in res) + '\n')
  2. 通过flow.request.path获取到ei(只写了处理res的那段代码)
    paths = flow.request.path[10:].split("&") # 用&分割查询参数 for path in paths: if path.split('=')[0] == 'ei': # 如果参数是ei p1 = path.split('=')[1] # 获取ei的值 p1 = urllib.parse.unquote(p1).split('|') # urllib.parse.unquote(p1) 解码ei的值 # 值里面还有|分隔符,且中文没有被解码掉,用它再次分割字符串 res = [urllib.parse.unquote(p) for p in p1] # 再次解码每个子串
  3. 在命令行启动mitmproxy和chome, 在页面上操作,就能看到抓包的数据已经写入到了 maidian.txt
    PYTHONPATH=. mitmdump -p 8080 -s /Users/anna/mitm/req_counter.py
    利用mitmproxy提高埋点测试效率_python_05