明明是端午节,却因为疫情啥也干不了,啥也不会的我只好学学大佬们的文章了,卷起来!
本篇文章仅供交流学习,侵权删(满满的求生欲)
看了3篇有关万方的文章,下面是链接,不过我也会讲的很详细滴。遇到的坑我会一一说出来。 blog.csdn.net/weixin_4341…
那么就开始吧。 首先网址是:aHR0cHM6Ly9zLndhbmZhbmdkYXRhLmNvbS5jbi9wYXBlcg==
怎么发请求
随便搜索一点东西
那么我们就要先解决发请求的问题
1.首先打开fiddler抓包,请求查看选择HexView,然后选择一定范围黑色的十六进制数(),然后右击选择save selected bytes保存为.bin文件,比如保存为source_form_data.bin文件,放到桌面上
然后打开pycharm
import requests,blackboxprotobuf
with open(r"C:\Users\Administrator\Desktop\source_form_data.bin", "rb") as fp:
data = fp.read()
deserialize_data, message_type = blackboxprotobuf.protobuf_to_json(data)
print(f"原始数据: {deserialize_data}")
print(f"消息类型: {message_type}") # 消息类型
这个时候,一定范围的作用就出来了,根据我的试验,如果选择全部黑色的字节保存,运行上面的代码会报错,如果报错了,就比图片上多往前选择一个字节,多尝试,这是第一个坑
运行完会发现打印出了这样的数据。
直接把上面的复制下来,然后定义两个变量(我这里不一样是因为后期有修改,不重要)
deserialize_data = {
"1": [
{
"1": "paper",
"2": "dd",
"5": "1",
"6": "20",
"8": "\u0000"
}
]
}
message_type = {'1': {'type': 'message', 'message_typedef': {'1': {'type': 'bytes', 'name': ''}, '2': {'type': 'bytes', 'name': ''}, '5': {'type': 'bytes', 'name': ''}, '6': {'type': 'bytes', 'name': ''}, '8': {'type': 'bytes', 'name': ''}}, 'name': ''}, '0': {'type': 'bytes', 'name': ''}, '2': {'type': 'bytes', 'name': ''}}
第二个坑是要把原始数据和消息类型后面数据的type对应上,是字符串,就改成bytes就好了,像上面这个图里面就全是字符串嘛,所以消息类型中的int就都要改成bytes,改完后就是上面的代码
2.现在我们可以发请求了
form_data = bytes(blackboxprotobuf.encode_message(deserialize_data,message_type))
response = requests.post(url, headers=headers, data=form_data,timeout=10,verify=False)
response_data,response_type = blackboxprotobuf.protobuf_to_json(response.content)
print(response_data)
但是你会发现请求有时候成功有时候不成功,而且就算成功返回也是空
这个时候就要构造字节序列的头部,修改后代码
form_data = bytes(blackboxprotobuf.encode_message(deserialize_data,message_type))
bytes_head = bytes([0, 0, 0, 0, len(form_data)])
response = requests.post(url, headers=headers, data=bytes_head+form_data,timeout=10,verify=False)
response_data,response_type = blackboxprotobuf.protobuf_to_json(response.content)
print(response_data)
第三个坑来了!!!!现在每次请求都会成功,但是还是不返回数据!在反复观摩3篇文章后都没有发现有用的信息,大佬们好像都是直接请求就成功了,反复思考后,我决定使用fiddler抓包自己python发出的请求,然后和网站发出的请求做对比,看看到底有哪里不同!
图一,是我python发出的请求
图二,这是我python构造的原始数据
图三,是网站发出的请求
图一和图三,一比较,就很明显了,好像前后多了点东西,最后多的0…22…1,是不是就是图二中的最后"0"和"2"对应的数据,既然多了,我们就把它删掉! 最终我构造的原始数据
就是这样了,打印一下response.content,然后你就会发现,请求返回了数据!密密麻麻一大堆。 但是转成json又会报错
ValueError: Invalid wiretype for field number 0. int is not wiretype 1
这个的原因看文章所说可能是前后有一些没用的字节,要把它去掉
首先我们选择响应数据的前5个字节
然后去16进制转10进制网站转一下
那么数据对应的位数就应该是63630(至于为什么前5个字节就是数据的长度,我也还不了解,如果有大佬可以解答一下,感谢!)
而我们看下图中响应数据的长度是63655,去掉前5位,63655-63630-5 = 20,所以后面20位也是没用的字节,我们可以请求完对response.content进行切片去掉前后没用的字节。这是第四个坑,也是最后一个坑
所以最后的代码就是
form_data = bytes(blackboxprotobuf.encode_message(deserialize_data,message_type))
bytes_head = bytes([0, 0, 0, 0, len(form_data)])
response = requests.post(url, headers=headers, data=bytes_head+form_data, cookies=cookies,timeout=10,verify=False,proxies={'http': 'http://127.0.0.1:8888', 'https': 'http://127.0.0.1:8888'})
print(response.content)
response_data,response_type = blackboxprotobuf.protobuf_to_json(response.content[5:-20])
print(response_data)
print(response)
结果也出来了,好耶!