Python CSV转JSON脚本重复读取行问题排查求助
问题排查与解决方案
首先,从你的输出和代码来看,有两个核心问题需要解决:
1. UTF-8 BOM 编码异常
你的输出里Code字段开头出现了\uFEFF,这是UTF-8文件的字节顺序标记(BOM)。这说明你的CSV文件是带BOM的UTF-8编码,但Python默认的文件读取逻辑不会自动处理这个标记,导致它被当作内容的一部分读了出来。
2. 每行重复4次的问题
结合你的代码和输出,最可能的原因有两个:
可能性一:CSV文件本身存在重复行
你的CSV文件里可能每一行数据被重复写入了4次(比如手动复制、生成CSV时的程序错误),脚本只是忠实地读取了所有行。你可以直接打开CSV文件检查,确认是否存在连续重复的条目。
可能性二:表头与代码参数不匹配
如果你的CSV文件本身有表头行(比如第一行是Code,Currency,Rate,Last Updated),但你在csv.DictReader里指定了fieldnames参数,这会导致表头行被当作普通数据行读取。如果后续数据行又重复了表头的内容,就会出现重复条目(不过从你的输出看,这个可能性相对低,但也需要排查)。
修复后的代码
我帮你优化了代码,同时解决编码问题和重复行的问题:
import csv import json from collections import OrderedDict fieldnames = ("Code", "Currency", "Rate", "Last Updated") entries = [] # 使用utf-8-sig编码读取,自动处理UTF-8 BOM with open('rates.csv', 'r', encoding='utf-8-sig') as csvfile: # 重点:如果你的CSV文件本身有表头行,不要指定fieldnames,让DictReader自动识别 # 如果CSV没有表头,再保留fieldnames参数 reader = csv.DictReader(csvfile) # 无表头的情况用这行:reader = csv.DictReader(csvfile, fieldnames=fieldnames) # 新增去重逻辑:避免重复添加相同条目 seen_entries = set() for row in reader: # 把行数据转成可哈希的元组,用于判断是否重复 row_key = tuple(row.items()) if row_key not in seen_entries: seen_entries.add(row_key) # 直接复用row即可,无需手动循环构建OrderedDict(除非你需要严格字段顺序) entry = OrderedDict(row) entries.append(entry) output = { "rates": entries } with open('rates2.json', 'w', encoding='utf-8') as jsonfile: json.dump(output, jsonfile, indent=2, ensure_ascii=False) jsonfile.write('\n')
关键修改说明
- 编码处理:用
encoding='utf-8-sig'打开文件,自动去除UTF-8 BOM,解决\uFEFF的乱码问题。 - 表头适配:根据CSV文件是否有表头,灵活选择是否保留
fieldnames参数,避免把表头当作数据行读取。 - 去重逻辑:添加了去重代码,即使CSV里有重复行,也只会保留一个条目,直接解决重复4次的问题。
- 代码简化:
csv.DictReader返回的row本身就是字典结构,不需要手动循环fieldnames构建OrderedDict,除非你需要严格保持字段顺序。
额外排查步骤
打开你的CSV文件确认:
- 是否存在连续重复的数据行;
- 第一行是否是表头(如果是,就不要在代码里指定
fieldnames); - 字段分隔符是否是逗号(如果是分号/制表符,需要在
csv.DictReader里添加delimiter=';'或delimiter='\t'参数)。
内容的提问来源于stack exchange,提问作者MattJSUK
相关产品推荐
相关产品推荐

