Python实现大JSON文件中通知本地化文本替换求助
问题描述
我需要自动替换一个30MB大型JSON文件中的字符串,文件结构示例如下:
通知部分:
"local_notifications": [ { "is_enabled": false, "notification_type": "basic", "notification_title": "localised_strings.show_name_debug_lobbies", "notification_body": "localised_strings.show_desc_debug_lobbies", "schedule": { "schedule_type": "dynamic", "elapsed_time": [ { "days": 0, "hours": 0, "minutes": 1 } ] }, "priority": 0, "priority_override": false, "id": "debug_notification" } ]
本地化字符串部分:
"localised_strings": [ { "text": "Debug lobbies", "id": "show_name_debug_lobbies" }, { "text": "Debug lobbies 2", "id": "show_desc_debug_lobbies" } ]
目标是将notification_title和notification_body字段中的值(格式为localised_strings.xxx)替换为localised_strings数组中对应id的text值。我已有解密该加密文件的Python代码,需要在此基础上实现替换功能。
解密代码如下:
import argparse from argparse import RawTextHelpFormatter xor_key = [0x61, 0x23, 0x21, 0x73, 0x43, 0x30, 0x2c, 0x2e] description = ('Decrypt or encrypt content_v1 of Fall Guys: Ultimate Knockout\n' 'content_v1 is usually found inside %UserProfile%\AppData\LocalLow\Mediatonic\FallGuys_client') argument_parser = argparse.ArgumentParser(description=description, formatter_class=RawTextHelpFormatter) argument_parser.add_argument('input_file', help='content_v1 or a valid JSON file') argument_parser.add_argument('output_file') arguments = argument_parser.parse_args() content = bytearray() content_idx = 0 try: with open(arguments.input_file, 'rb') as input_file: while (byte := input_file.read(1)): content += bytes([ord(byte) ^ xor_key[content_idx % (len(xor_key))]]) content_idx += 1 except (IOError, OSError) as exception: print('Error: could not read input file') exit() try: with open(arguments.output_file, 'wb') as output_file: output_file.write(content) except (IOError, OSError) as exception: print('Error: could not create output file') exit()
解决方案
我们可以将解密、JSON处理、加密(可选)整合到一个脚本中,步骤如下:
- 解密文件:使用已有逻辑读取并解密加密文件,得到可解析的JSON文本。
- 构建本地化映射:从JSON中提取
localised_strings,创建id到text的字典,实现快速查找。 - 替换通知字段:遍历
local_notifications条目,解析标题和内容中的ID,替换为对应本地化文本。 - 输出结果:可选择输出修改后的解密JSON,或重新加密后保存。
完整代码
import argparse import json from argparse import RawTextHelpFormatter xor_key = [0x61, 0x23, 0x21, 0x73, 0x43, 0x30, 0x2c, 0x2e] description = ('Decrypt, replace localisation strings, and optionally re-encrypt content_v1 of Fall Guys: Ultimate Knockout\n' 'content_v1 is usually found inside %UserProfile%\AppData\LocalLow\Mediatonic\FallGuys_client') argument_parser = argparse.ArgumentParser(description=description, formatter_class=RawTextHelpFormatter) argument_parser.add_argument('input_file', help='content_v1 or a valid JSON file') argument_parser.add_argument('output_file') argument_parser.add_argument('--reencrypt', action='store_true', help='Re-encrypt the modified JSON before saving') args = argument_parser.parse_args() def xor_crypt(data): """XOR加密/解密通用函数""" content = bytearray() content_idx = 0 for byte in data: content.append(byte ^ xor_key[content_idx % len(xor_key)]) content_idx += 1 return content # 1. 读取并解密文件 try: with open(args.input_file, 'rb') as f: encrypted_data = f.read() decrypted_data = xor_crypt(encrypted_data) except (IOError, OSError) as e: print(f'读取输入文件出错: {e}') exit(1) # 2. 解析JSON并执行替换 try: json_data = json.loads(decrypted_data.decode('utf-8')) # 构建本地化ID到文本的映射表 localisation_map = {} for item in json_data.get('localised_strings', []): loc_id = item.get('id') if loc_id: localisation_map[loc_id] = item.get('text', '') # 遍历通知列表替换字段 for notification in json_data.get('local_notifications', []): # 处理标题字段 title_key = notification.get('notification_title', '') if title_key.startswith('localised_strings.'): target_id = title_key.split('.', 1)[1] notification['notification_title'] = localisation_map.get(target_id, title_key) # 处理内容字段 body_key = notification.get('notification_body', '') if body_key.startswith('localised_strings.'): target_id = body_key.split('.', 1)[1] notification['notification_body'] = localisation_map.get(target_id, body_key) # 生成修改后的JSON字节数据 modified_json = json.dumps(json_data, indent=2, ensure_ascii=False) modified_bytes = modified_json.encode('utf-8') except json.JSONDecodeError as e: print(f'解析JSON出错: {e}') exit(1) except Exception as e: print(f'处理数据出错: {e}') exit(1) # 3. 保存结果(可选加密) try: output_data = xor_crypt(modified_bytes) if args.reencrypt else modified_bytes with open(args.output_file, 'wb') as f: f.write(output_data) print(f'处理完成,结果已保存到 {args.output_file}') except (IOError, OSError) as e: print(f'写入输出文件出错: {e}') exit(1)
使用说明
- 输出修改后的解密JSON:
python script.py 输入文件路径 输出文件路径 - 修改后重新加密输出:
python script.py 输入文件路径 输出文件路径 --reencrypt
注意事项
- 30MB的JSON文件解析会占用一定内存,确保系统有足够资源(8GB以上内存无压力)。
- 若实际JSON结构与示例有差异,需调整代码中对应的字段名称。
- 处理前请备份原始文件,避免数据丢失。
内容的提问来源于stack exchange,提问作者Didoub74
相关产品推荐
相关产品推荐

