You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

尽管使用UTF8编码,S3输出仍出现'Â'字符的问题排查

从S3读取CSV写入后出现大量'Â'字符的编码问题解决

我在Glue Notebook中执行任务:从S3拉取多个CSV文件,格式化合并后推回S3。但输出文件中出现大量Â字符,即使仅读取后直接写回,空格等位置也会出现该字符,推测问题出在write_to_s3函数的编码设置上。

现有代码

读取与合并代码

import pandas as pd
import numpy as np
import boto3
import io

s3_client = boto3.client("s3")
S3_BUCKET_NAME = "bucket"
S3_PREFIX_Manufacturer = "Cost/Data_Source/Manufacturer"

def read_from_s3(object_key):
    file_content = s3_client.get_object(Bucket=S3_BUCKET_NAME, Key=object_key)["Body"].read()
    return pd.read_csv(io.BytesIO(file_content),  header=0)

data = pd.DataFrame()
# 示例仅用单个文件,函数支持多文件合并
manuf_data = ["Manufacturer_Report_(Jan5)_UTF8.csv"] 

for manuf in manuf_data:
    object_key = f"{S3_PREFIX_Manufacturer}/{manuf}"
    df = read_from_s3(object_key)
    data = pd.concat([data, df])

写入S3代码

def write_to_s3(df, bucket, key):
    body = df.to_csv(index=False, encoding="cp1252") # 曾尝试encoding="utf-8-sig"
    s3_client.put_object(Body=body, Bucket=bucket, Key=key)

processed_key = "Cost/Data_Source/Manufacturer/test.csv"
write_to_s3(data, S3_BUCKET_NAME, processed_key)

输入输出示例

输入CSV内容

Part NumberManufacturersManufacturer Code
112000Zebra ~ ElephantZX123 ~ XY45
113000Giraffe ~ Lion ~ TigerABC-123 ~ 300100 ~ TIGER 23
114000No Manufacturer GivenNo Manufacturer Given

写入后输出CSV内容

Part NumberManufacturersManufacturer Codes
112000Zebra ~ Elephant, IncZX123 ~ XY45
113000Giraffe Co. ~ Lion ~ Tiger Corp.ABC-123 ~ 300100 ~ TIGER 23
114000No Manufacturer GivenNo Manufacturer Given

问题原因与解决方法

Â字符是典型的编码不匹配导致的乱码:UTF-8编码的多字节字符(如非标准空格0xC2A0)被当作单字节编码(如CP1252)解析时,会拆分出Â字符。结合你的场景,问题出在读取和写入的编码一致性上:

1. 读取时明确指定UTF-8编码

源文件名包含UTF8,说明文件是UTF-8编码(可能带BOM),读取时需明确指定编码,避免pandas使用系统默认编码读取:

def read_from_s3(object_key):
    file_content = s3_client.get_object(Bucket=S3_BUCKET_NAME, Key=object_key)["Body"].read()
    # 指定UTF-8编码读取,处理可能的BOM
    return pd.read_csv(io.BytesIO(file_content), header=0, encoding="utf-8-sig")

2. 写入时直接输出字节流,避免编码二次转换

原代码中df.to_csv(encoding="cp1252")生成CP1252编码的字符串,传递给put_object时Python会自动将其编码为UTF-8字节流,导致二次编码乱码。改用字节流直接写入,确保编码一致:

def write_to_s3(df, bucket, key):
    # 生成UTF-8带BOM的字节流,直接写入S3
    buffer = io.BytesIO()
    df.to_csv(buffer, index=False, encoding="utf-8-sig")
    buffer.seek(0)  # 重置流指针到开头
    s3_client.put_object(Body=buffer, Bucket=bucket, Key=key)

原理说明

  • utf-8-sig编码会自动处理UTF-8文件的BOM头,确保读取和写入时字符解析正确;
  • 使用BytesIO直接生成字节流,跳过字符串到字节的转换步骤,避免Python默认编码干扰,保证写入的字节流与指定编码完全一致。

内容的提问来源于stack exchange,提问作者silliw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:27:04