多维列表转JSON及数据查询优化:TsumTsum爬虫开发问题
我来帮你一步步解决这个问题——你现在在做迪士尼TsumTsum角色的Python爬虫,需要把现有的多维数组转成JSON,还要实现查询和筛选功能,同时处理好80余种分类属性的存储。咱们从核心的问题开始拆解:
1. 先设计合理的JSON数据结构(这是后续一切的基础)
你提到现在把数据拆分到多个单维列表里,这种结构确实不利于后续查询和筛选。最适合你的需求的结构是「字典组成的列表」:每个角色对应一个字典,包含name(角色名)、tags(分类属性的数组,用来存那80余种分类里匹配的10种),以及其他你需要的属性(比如稀有度、技能效果等)。示例结构如下:
[ { "name": "米老鼠", "tags": ["经典角色", "鼠类", "主角"], "rarity": "SSR", "skill": "消除全屏Tsum" }, { "name": "唐老鸭", "tags": ["经典角色", "鸭类", "喜剧角色"], "rarity": "SR", "skill": "生成炸弹道具" } ]
这种结构的好处:
- 单个文件就能存所有数据,JSON格式易读易写,Python自带
json模块就能处理 - 每个角色的属性一目了然,方便后续查询和筛选
tags数组天然适配「一个角色对应多个分类属性」的需求,80余种分类完全能覆盖
2. 从多维数组转JSON的具体实现
假设你现在的多维数组是类似这样的结构(每个子数组对应一个角色的原始数据):
raw_data = [ ["米老鼠", ["经典角色", "鼠类", "主角"], "SSR", "消除全屏Tsum"], ["唐老鸭", ["经典角色", "鸭类", "喜剧角色"], "SR", "生成炸弹道具"] ]
你可以写一段代码把它转换成上面的字典列表,再保存为JSON文件:
import json def convert_to_json(raw_data, output_file): processed_roles = [] for item in raw_data: # 从多维数组里提取每个角色的字段 role = { "name": item[0], "tags": item[1], # 这里如果你的tags是嵌套列表,后面会讲怎么处理 "rarity": item[2], "skill": item[3] } processed_roles.append(role) # 保存到单个JSON文件,ensure_ascii=False避免中文乱码,indent=2让格式更美观 with open(output_file, "w", encoding="utf-8") as f: json.dump(processed_roles, f, indent=2, ensure_ascii=False) # 调用示例 convert_to_json(raw_data, "tsum_tsum_data.json")
3. 实现核心的查询与筛选功能
有了规范的JSON数据结构,这两个功能就非常好实现了:
根据角色名查询属性
为了提高查询效率(尤其是80+角色的规模),可以先把数据加载到内存后,建立一个「角色名→角色字典」的索引字典,这样查询就是O(1)的速度:
def load_role_data(json_file): with open(json_file, "r", encoding="utf-8") as f: roles = json.load(f) # 建立索引字典 role_index = {role["name"]: role for role in roles} return roles, role_index # 加载数据 all_roles, role_index = load_role_data("tsum_tsum_data.json") # 查询函数 def get_role_attributes(role_name): return role_index.get(role_name, f"未找到角色:{role_name}") # 示例:查询米老鼠的属性 print(get_role_attributes("米老鼠"))
根据特质筛选角色
比如筛选所有带有「经典角色」标签的角色,或者同时满足多个标签的角色,用列表推导式就能轻松实现:
# 单标签筛选 def filter_roles_by_tag(tag): return [role for role in all_roles if tag in role["tags"]] # 示例:获取所有经典角色 classic_roles = filter_roles_by_tag("经典角色") print([role["name"] for role in classic_roles]) # 多标签筛选(同时满足所有标签) def filter_roles_by_tags(tags): return [role for role in all_roles if all(tag in role["tags"] for tag in tags)] # 示例:获取既是经典角色又是鼠类的角色 mouse_classic_roles = filter_roles_by_tags(["经典角色", "鼠类"])
4. 解决嵌套列表的处理问题
你提到当前代码有列表嵌套处理的问题,比如如果你的分类属性是嵌套在多层列表里的(比如["经典角色", ["鼠类", "主角"]]),可以先写一个扁平化函数把嵌套列表转成一维数组:
def flatten_nested_list(nested_list): flat_list = [] for item in nested_list: if isinstance(item, list): # 递归处理嵌套的子列表 flat_list.extend(flatten_nested_list(item)) else: flat_list.append(item) return flat_list # 示例:处理嵌套的tags nested_tags = ["经典角色", ["鼠类", "主角"]] flat_tags = flatten_nested_list(nested_tags) # 输出:["经典角色", "鼠类", "主角"]
把这个函数集成到之前的转换代码里,就能确保tags始终是一维数组,方便后续的筛选和查询。
内容的提问来源于stack exchange,提问作者Travis Foster
相关产品推荐
相关产品推荐

