万方 protobuf 反序列化

news/2024/10/23 9:25:30/

protobuf 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。
在网络传输方面,相比传统的json,有着更快、更小,且加密性好的特点。


在实际应用中,万方数据库官网发送的请求,就用到了这。
一般网站,比如cnki,我们检索内容,只需要拼接一个http请求,便能获取到数据。
在这里插入图片描述



但是,万方数据库,却是这样的,看不到请求body都是一些乱码一样的数据,连返回的数据也是。
在这里插入图片描述
在这里插入图片描述



这正是由于其使用了protobuf序列化,我们通过它发送请求头中也可以看到有 “application/grpc-web+proto” 这样的字样。
在这里插入图片描述




其大致流程:实例化一个proto格式对象(长得类似c的结构体),将检索式塞到该对象属性中,对其进行序列化为二进制,发送请求,对接收到的数据进行反序列化。
因此我们重点就在于拿到这个proto对象的结构。



有关万方protobuf发送请求的大部分内容,可以参考大佬的文章: https://blog.csdn.net/qq_35491275/article/details/111721639



这里就只对拿到数据,将其反序列化的大致步骤,进行讲解。
本人是通过python发送请求,根据上面参考文章说的,要将数据反序列化,便需要获取到proto格式,比如有哪些变量和变量类型。
而这都需要通过在浏览器F12,打断点,一步步调试js函数才能获得。本人由于对js不了解,也不太会调试js,所以也是变相换个方法去实现。



F12------》Source------》XHR/fetch Breakpoints,将接口请求地址复制进去,这样调试的时候就会自动在相关位置断点了。
在这里插入图片描述



在Call Stack调用栈中,看到了SearchService字样,点击进去。
在这里插入图片描述
在这里插入图片描述



后面通过打断点,一步步调试,便能在一些方法名中找到需要的变量和类型。
本人这里就不做调试,我说说自己当时的思路。

因为整个检索流程,就主要经过了两份js,所以我直接ctrl+F,搜索SearchService字样,发现都在api.1f9fdaa9.js这一份当中。
然后我再ctrl+F,搜索 “toObject = function(e, t) {” 字样,一般每个message结构对应的变量名和序号就在这个函数中,变量类型则一般在 “serializeBinaryToWriter = function(e, t) {” 函数中,大概有90多个匹配的。这一步不清楚可以看上面参考博客,便知道为什么这样找这些message结构。将他们列出来,写入一份.proto文件中。
这里变量名好像可以自己命名,主要是序号需要保持一致,但为了解析数据方便,这里变量名也尽量保持了和js中的一致,最终得到右边的proto文件。
在这里插入图片描述


在这里插入图片描述


在这里插入图片描述




然后通过protoc.exe编译器,输入命令 protoc proto文件名 --python_out=./ 得到相关py文件。

在这里插入图片描述




新建一个python工程,将刚刚生成的py文件丢入工程中。便可成功反序列化出数据。

在这里插入图片描述


这里请求时使用了blackboxprotobuf模块,可以减少去获取请求的proto结构这一步骤。具体一些点的可以参考他人博客。

参考代码:main.py

# This is a sample Python script.# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.import blackboxprotobuf
import urllib
from urllib import parse
import requests
import tkinter
import asyncio
import os
import wf_proto_pb2 as wf_proto_pb2def intToBytes(value, length):result = []for i in range(0, length):result.append(value >> (i * 8) & 0xff)result.reverse()return resultdef prowfdata(response):# 转码response = str(response.encode('latin1').decode('unicode-escape').encode('latin1').decode('utf-8'))return responsedef searchw(searchkey):searchkey = urllib.parse.unquote(searchkey)json = eval(searchkey)url = json["url"]headers = json["headers"]deserialize_data = json["deserialize_data"]message_type = json["message_type"]unwanted_bytes = json["unwanted_bytes"]proxies = {'http': 'http://127.0.0.1:8888', 'https': 'http://127.0.0.1:8888'}form_data = bytes(blackboxprotobuf.encode_message(deserialize_data, message_type))bytes_head = bytes(intToBytes(len(form_data), 5))requests.packages.urllib3.disable_warnings()try:response = requests.post(url=url, headers=headers,data=bytes_head + form_data, timeout=10, verify=False)except Exception as e:response = requests.post(url=url, headers=headers,data=bytes_head + form_data, timeout=10, verify=False, proxies=proxies)search_response2 = wf_proto_pb2.SearchService_SearchResponse()search_response2.ParseFromString(response.content[5:])return prowfdata(str(search_response2))if __name__ == '__main__':searchkey = '{"url":"https://s.wanfangdata.com.cn/SearchService.SearchService/search","headers":{"accept":"*/*","Referer":"https://s.wanfangdata.com.cn","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36","Content-Type":"application/grpc-web+proto",},"deserialize_data":{"1":{"1":"paper","2":"(题名:(dna))","4":{"1":"Type","2":"(Periodical OR Thesis OR Conference)"},"5":1,"6":10,"8":"\\u0000"},"2":3},"message_type":{"1":{"type":"message","message_typedef":{"1":{"type":"bytes", "name":""}, "2":{"type":"bytes", "name":""},"4":{"type":"message","message_typedef":{"1":{"type":"bytes", "name":""},"2":{"type":"bytes", "name":""}},"name":""}, "5":{"type":"int", "name":""},"6":{"type":"int", "name":""}, "8":{"type":"bytes", "name":""}},"name":""}, "2":{"type":"int", "name":""}},"unwanted_bytes":"0"}'print(searchw(searchkey))

http://www.ppmy.cn/news/139501.html

相关文章

如何使用宝塔面板搭建网站(搭建宝塔页面)

书接上回,咱们已经搭建好咱们的Linux服务器,接下来改是搭建宝塔页面的教程了。 这里我们需要一个域名,自行去各家云服务器购买域名(例如:腾讯云,阿里云,华为云等等) 购买一个域名之…

我的世界模组开发(0)MDK安装详解

万事开头难,开了头仍很难 就在暑假末,我的MDK坏了,不过,在我的力挽狂澜之下,MDK又被修好了 在修的时候,我放弃了Forge官方的MDK,因为有一个叫做client1.12.2.pom文件被墙了。。。。 无奈之下…

STM32CubeMX系列07——IIC通信(AT24C02、OLED屏幕)

文章目录 1. 准备工作1.1. 所用硬件1.2. IIC简介1.2. 生成工程1.2.1. 创建工程选择主控1.2.2. 系统配置1.2.3. 配置工程目录1.2.4. IIC配置 2. 读写EEPROM实验(AT24C02)2.1. AT24C02简介2.1.1. AT24C02原理图2.1.2. 设备地址 2.2. 读写时序2.3. 代码实现…

华为 Mate40 手机

2020年10月22日,华为宣布推出2020年全新旗舰手机华为Mate40系列,华为Mate40系列实现强悍性能、全能影像和创新交互的空前突破,让人们对全场景智慧生活未来的构想更进一步。 华为Mate40 Pro和华为Mate40 Pro搭载华为首款5纳米麒麟9000 SoC芯片…

物料主数据的MRP视图详解

MRP组 MRP组是针对控制MRP运行参数的设置为一个组。MRP运行时考虑的参数可以是工厂级,也可以设置在MRP组级别。 ABC标识 根据消耗值,按物料ABC进行标识分类。A-重要部分,高消耗值 B-次重要,中等消耗 C-不重要。低消耗。MC40 和…

Cortex-M4架构

本文参考资料来自《ARM Cortex-M3与Cortex-M4 权威指南》 Cortex-M4 处理器基于ARMv7-M架构,发布时,架构中又额外增加了新的指令和特性,改进后的架构也被称为ARMv7E-M 编程模型 操作模式和状态 操作状态: - 调试状态&#xf…

MCMC

背景 给定一个的概率分布 p(x) , 我们希望产生服从该分布的样本。前面介绍过一些随机采样算法(如拒绝采样、重要性采样)可以产生服从特定分布的样本,但是这些采样算法存在一些缺陷(如难以选取合适的建议分布,只适合一…

机器学习常识 12: SVM

摘要: 支持向量机 (support vector machine, SVM) 有很多闪光点, 理论方面有 VC 维的支撑, 技术上有核函数将线性不可分变成线性可分, 实践上是小样本学习效果最好的算法. 1. 线性分类器 如图 1 所示, 基础的 SVM 仍然是一个线性二分类器, 这一点与 logistic 回归一致. 图 1.…