目录
前言
基本思路:抓包获取http包,分析数据格式,生成数据,上传数据
一、抓包
使用Fiddler 对http包进行抓包
获得请求头:
POST http://10.11.246.182:8029/DragonFlyServ/Api/webserver/uploadRunData HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
Charset: UTF-8
User-Agent: Dalvik/2.1.0 (Linux; U; Android 11; M2011K2C Build/RKQ1.200928.002)
Host: 10.11.246.182:8029
Accept-Encoding: gzip
二、分析数据
1.解码请求主体
在16进制下可以看到post请求主体部分是乱码,联合请求头可以得知数据进行了gzip压缩。
在python中引入gzip,对数据进行解压。
import gzip
import sys
import json
def main():
f= gzip.open(r'\data','rb')
file_content = f.read()
print(file_content)
f.close()
if __name__ == "__main__":
sys.exit(int(main() or 0))
2.分析数据
结合jadx分析软件本体,可以得知数据格式如下:
{'begintime':'" + rundata.split(",")[0] + "',
'endtime':'" + rundata.split(",")[1] + "',
'uid':'" + times.split(",")[1] + "',
'schoolno':'" + schoolno + "',
'distance':'" + distance + "',
'speed':'" + speed + "',
'studentno':'" + times.split(",")[0] + "',
'atttype':'" + atttype + "',
'eventno':'" + eventno + "',
'location':'" + location + "',
'pointstatus':'" + pointstatus + "',
'usetime':'" + time + "'}
三、生成数据
1.时间数据
通过引入time可获得当前时间
import time
t = int(time.time())
2.跑步数据
因为数据分析中发现跑步数据以3到4秒为一段分割,结合基本的计算可以得知,每段数据应以10米左右进行分割。因为跑步区域小,可以将经纬度近似于平面坐标系进行分割。
import geopy
from geopy import distance
d = distance.distance(loc1, loc2).meters #计算两点间距离
c = d // 10 #计算分割段数
lats = (lat[1]) - lat[0]) / c #计算每段增量
lons = (lon[1]) - lon[0]) / c
m = 1
while m < c:
latf.append(float(lat[0]) + lats * m )
lonf.append(float(lon[0]) + lons * m )
m = m + 1
3.打包封装
以上面分析的数据格式进行打包
i = 0
while i < c:
line = str(latf[i]) + '0,' + str(lonf[i]) + '0;' + str(tc[i]) + ';null;null;'+str(round(random.uniform(2.5,1.5),1))+';null'
gpsd.append(line)
i = i + 1
gdata = '@'.join(gpsd)
四、上传数据
通过此前的数据分析和数据生成,我们已经得到了一个data字典,可以通过gzip压缩后使用requests库进行post。
import gzip
import requests
headers = {"Connection": "Keep-Alive", "Charset": "UTF-8",
"User-Agent": "Dalvik/2.1.0 (Linux; U; Android 11; M2011K2C Build/RKQ1.200928.002)",
"Host": "10.11.246.182:8029"}
url = r'http://10.11.246.182:8029/DragonFlyServ/Api/webserver/getRunDataSummary'
f_out = gzip.compress(str(data).encode('utf-8'))
requ = requests.post(url=url, headers=headers, data=f_out)
print(requ.text)
总结
在整个项目中,我花在post上的时间最多,网上post gzip数据多数通过数据流的方式,而在这个项目中数据流不被服务器接受,最后在gzip的说明文档中找到可以直接对二进制进行压缩,通过指定post data 以表单文字的方法进行post,最后的抓包结果表明和手机软件中生成的post请求格式有所不同,猜测是gzip压缩等级不同导致。最后服务器返回正常结果。