Python读取JSON异常:按PhotoImgID匹配重命名图片全失败求助
问题:图片批量重命名脚本全部执行失败
需求为编写Python脚本遍历文件夹中所有JSON文件,为每张图片找到PhotoImgID与图片名称一致的JSON,将图片重命名为JSON中Name字段的值,但当前脚本处理所有图片均失败。
用户提供的核心代码片段
with open(json_path, 'r') as file: try: json_data = json.load(file) # Check if the JSON data contains the required fields if all(field in json_data for field in ['Name', 'PhotoImgID']): photo_img_id = json_data['PhotoImgID'] # Check if the photo ID matches the JSON's PhotoImgID if photo_id == photo_img_id: new_filename = json_data['Name'] + os.path.splitext(photo_path)[1] # Generate new filename new_photo_path = os.path.join(photo_folder, new_filename) # Rename the photo shutil.move(photo_path, new_photo_path) match_found = True break # Stop searching JSON files once a match is found except (json.JSONDecodeError, KeyError) as e: print(f'Error processing {json_path}: {e}') if not match_found: not_found_photos.append(filename)
样本JSON内容
{ "Name": "Adhithya G", "SecName": "A", "DeptCode": "CSE", "Sex": "F", "PhotoImgID": "6368f927d6c5dfea4ca57c62" }
常见失败原因及修复方案
1. 图片ID提取错误
- 问题:
photo_id可能包含图片扩展名(如6368f927d6c5dfea4ca57c62.jpg),但JSON中的PhotoImgID是纯ID字符串,导致匹配失败。 - 修复:提取图片文件名时去除扩展名:
filename = os.path.basename(photo_path) photo_id = os.path.splitext(filename)[0] # 仅保留文件名部分,剔除后缀
2. 遍历范围不完整
- 问题:脚本可能未遍历所有JSON文件,或仅处理了单个JSON文件。
- 修复:确保遍历目标文件夹下所有
.json文件,完整脚本如下:
import os import json import shutil # 替换为你的图片和JSON文件夹路径 photo_folder = "./photos" json_folder = "./jsons" not_found_photos = [] # 遍历所有图片文件 for filename in os.listdir(photo_folder): photo_path = os.path.join(photo_folder, filename) # 跳过文件夹和非图片文件 if not os.path.isfile(photo_path) or not filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): continue photo_id = os.path.splitext(filename)[0] match_found = False # 遍历所有JSON文件查找匹配项 for json_filename in os.listdir(json_folder): if not json_filename.lower().endswith('.json'): continue json_path = os.path.join(json_folder, json_filename) with open(json_path, 'r', encoding='utf-8') as file: try: json_data = json.load(file) # 检查必要字段是否存在 if 'Name' in json_data and 'PhotoImgID' in json_data: if json_data['PhotoImgID'] == photo_id: # 处理Name中的非法文件名字符 invalid_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|'] valid_name = json_data['Name'] for char in invalid_chars: valid_name = valid_name.replace(char, '_') # 生成新文件名,避免重复 new_filename = f"{valid_name}{os.path.splitext(filename)[1]}" new_photo_path = os.path.join(photo_folder, new_filename) counter = 1 while os.path.exists(new_photo_path): new_filename = f"{valid_name}_{counter}{os.path.splitext(filename)[1]}" new_photo_path = os.path.join(photo_folder, new_filename) counter += 1 # 执行重命名 shutil.move(photo_path, new_photo_path) match_found = True break except json.JSONDecodeError as e: print(f"解析JSON失败 {json_path}: {e}") except Exception as e: print(f"处理文件出错 {json_path}: {e}") if not match_found: not_found_photos.append(filename) # 输出结果 if not_found_photos: print("未找到匹配JSON的图片:") for photo in not_found_photos: print(photo) else: print("所有图片均已成功重命名")
3. JSON文件编码问题
- 问题:JSON文件可能采用非UTF-8编码,导致读取失败。
- 修复:打开JSON文件时指定
encoding='utf-8',如上述完整脚本所示。
4. 文件名含非法字符
- 问题:
Name字段可能包含操作系统禁止的文件名字符(如/、:),导致重命名失败。 - 修复:对
Name字段进行非法字符替换,上述脚本已包含该处理逻辑。
5. 重复文件名冲突
- 问题:多张图片匹配到相同
Name,导致重命名时覆盖或失败。 - 修复:添加计数器,重复时自动在文件名后追加数字后缀,避免冲突。
内容的提问来源于stack exchange,提问作者dhanushkkar
相关产品推荐
相关产品推荐

