使用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的操作完全无效。以下是修复方案:
修复步骤
- 替换
StringIO为BytesIO,直接处理字节流,避免字符串编码二次转换的误差。 - 使用
utf-8-sig编码写入CSV,该编码会添加UTF-8 BOM标记,确保阿拉伯语等非ASCII字符被正确识别。 - 移除无效的编码转换代码。
修复后代码
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
相关产品推荐
相关产品推荐

