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

使用boto3存储CSV到S3时阿拉伯语内容乱码问题求助

问题描述

使用Python的boto3库将CSV文件存储到S3桶时,文件中的阿拉伯语内容出现乱码。尝试过UTF-8和UTF-16编码,问题仍未解决。

输入CSV示例

Route ID
SOK Cement plant - ISMAILIA-ISMAILIA_001E - EGCAIS0001_100710536_القناة للمواني و المشروعات الكبرى EGCAIS0001
SOK Cement plant - DAMIETA-DAMIETA_001E - EGEDDA0001_C081E_دمياط EGEDDA0001
SOK Cement plant - SUEZ-SUEZ_001E - EGCASU0035_101600411_كروز للتجارة - عتاقه EGCASU0035
SOK Cement plant - SUEZ-EIN SOKHNA_001E - EGCASU0036_101340099_يوني مكس - ميناء السخنة EGCASU0036

存储到S3后的输出CSV示例

Route ID
SOK Cement plant - SUEZ-EIN SOKHNA_001E - EGCASU0036_101340099_يوني مكس  - ميناء السخنة  EGCASU0036
SOK Cement plant - DAMIETA-DAMIETA_001E - EGEDDA0001_C081E_دمياط  EGEDDA0001
SOK Cement plant - SUEZ-SUEZ_001E - EGCASU0035_101600411_كروز للتجارة - عتاقه  EGCASU0035
SOK Cement plant - ISMAILIA-ISMAILIA_001E - EGCAIS0001_100710536_القناة للمواني و المشروعات الكبرى  EGCAIS0001

当前代码

final_SC_Result = calculatedRoutes[["Route ID", "Origin", "Destination"]]

final_SC_Result_encoded = final_SC_Result.applymap(lambda x: x.encode('utf-16').decode('utf-16') if isinstance(x, str) else x)
ShouldCost.objects.filter(should_cost_name=should_cost_name).update(lock_result=True,user_id=user_id)
csv_buffer = StringIO()
final_SC_Result_encoded.to_csv('final_SC_Result.csv',index=False)
#final_SC_Result.to_csv('final_SC_Result.csv', encoding="UTF-8", index=False)
final_SC_Result.to_csv(csv_buffer, encoding="UTF-8", index=False)
bucket_name = 'bucket_name'
folder_name = 'all_data/output/'
file_name = f"""Final_op_{should_cost_name}.csv"""
final_op_filename = folder_name + file_name
s3_resource = boto3.resource('s3')
s3_resource.Object(bucket_name, final_op_filename).put(Body=csv_buffer.getvalue())
解决方案

问题核心在于用StringIO处理UTF-8编码内容时的中间转换错误,且代码中final_SC_Result_encoded的操作完全无效。以下是修复方案:

修复步骤

  1. 替换StringIO为BytesIO,直接处理字节流,避免字符串编码二次转换的误差。
  2. 使用utf-8-sig编码写入CSV,该编码会添加UTF-8 BOM标记,确保阿拉伯语等非ASCII字符被正确识别。
  3. 移除无效的编码转换代码。

修复后代码

from io import BytesIO
import boto3

final_SC_Result = calculatedRoutes[["Route ID", "Origin", "Destination"]]

# 更新数据库记录
ShouldCost.objects.filter(should_cost_name=should_cost_name).update(lock_result=True, user_id=user_id)

# 用BytesIO存储CSV字节流
csv_buffer = BytesIO()
# 使用utf-8-sig编码,添加BOM确保字符识别正确
final_SC_Result.to_csv(csv_buffer, encoding='utf-8-sig', index=False)
# 将缓冲区指针移至开头
csv_buffer.seek(0)

bucket_name = 'bucket_name'
folder_name = 'all_data/output/'
file_name = f"Final_op_{should_cost_name}.csv"
final_op_filename = folder_name + file_name

s3_resource = boto3.resource('s3')
# 直接上传字节内容
s3_resource.Object(bucket_name, final_op_filename).put(Body=csv_buffer)

关键说明

  • utf-8-sig编码会在文件开头添加UTF-8 BOM,让Excel、文本编辑器等工具能正确识别UTF-8编码的非ASCII字符,彻底解决乱码问题。
  • BytesIO直接处理字节流,跳过字符串到字节的转换环节,减少编码错误概率。
  • 上传时直接传递csv_buffer即可,无需调用getvalue(),因为BytesIO对象可直接作为put方法的Body参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:27:36