使用UTF-8编码写入CSV时特殊字符显示异常问题
问题解决:Facebook Messenger数据导出CSV乱码及文件覆盖问题
你的脚本存在两个核心问题:每次写入都会覆盖之前的内容,以及UTF-8编码未被Excel正确识别,以下是具体修复方案:
问题分析
- 文件覆盖:你在循环内使用
'w'模式打开output.csv,这会在每次写入时清空文件,最终只保留最后一条消息。 - 编码乱码:Jørn显示为Jørn是典型的UTF-8编码被当作Latin-1(ISO-8859-1)解码的结果。Windows Excel默认不识别无BOM的UTF-8文件,导致重音字符解析错误。
修正后的脚本
import os import json from datetime import datetime from tqdm import tqdm import csv directory = "facebook-100071636101603/messages/inbox" folders = os.listdir(directory) if ".DS_Store" in folders: folders.remove(".DS_Store") # 外层打开CSV文件,避免重复IO操作 with open('output.csv', 'a', newline='', encoding="utf-8-sig") as csv_file: writer = csv.writer(csv_file) # 仅当文件为空时写入表头 csv_file.seek(0, os.SEEK_END) if csv_file.tell() == 0: writer.writerow(["日期", "发送者", "内容"]) for folder in tqdm(folders): print(folder) folder_path = os.path.join(directory, folder) for filename in os.listdir(folder_path): if filename.startswith("message"): file_path = os.path.join(folder_path, filename) # 读取JSON时显式指定UTF-8编码 with open(file_path, 'r', encoding='utf-8') as f: data = json.load(f) for message in data["messages"]: try: date = datetime.fromtimestamp(message["timestamp_ms"] / 1000).strftime("%Y-%m-%d %H:%M:%S") sender = message["sender_name"] content = message["content"] writer.writerow([date, sender, content]) except KeyError: # 跳过缺少字段的消息 continue
关键修改说明
- 文件模式改为
'a':以追加模式写入,保留之前的所有数据,避免覆盖。 - 使用
utf-8-sig编码:自动添加UTF-8 BOM标记,让Windows Excel能正确识别UTF-8字符,解决重音乱码问题。 - 外层打开CSV文件:减少重复打开/关闭文件的IO开销,提升效率。
- 添加表头判断:仅在文件为空时写入一次表头,避免重复写入。
- 显式指定JSON读取编码:确保读取Messenger的JSON文件时不会出现编码解析错误。
额外说明
如果用VS Code、Notepad++等支持UTF-8的文本编辑器打开原脚本生成的CSV,字符显示是正常的——问题仅出在Windows Excel对无BOM UTF-8的默认识别逻辑上。
内容的提问来源于stack exchange,提问作者uberts64
相关产品推荐
相关产品推荐

