万方 protobuf 反序列化

2023-10-14 21:20
文章标签 序列化 protobuf 万方

本文主要是介绍万方 protobuf 反序列化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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))

这篇关于万方 protobuf 反序列化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/213224

相关文章

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

SpringBoot项目中Redis存储Session对象序列化处理

《SpringBoot项目中Redis存储Session对象序列化处理》在SpringBoot项目中使用Redis存储Session时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在Spri... 目录一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及