Python 2.7 CSV 文件读/写 \xef\xbb\xbf 代码
Posted
技术标签:
【中文标题】Python 2.7 CSV 文件读/写 \\xef\\xbb\\xbf 代码【英文标题】:Python 2.7 CSV file read/write \xef\xbb\xbf codePython 2.7 CSV 文件读/写 \xef\xbb\xbf 代码 【发布时间】:2018-10-12 07:48:13 【问题描述】:我对带有“utf-8-sig
”代码的 Python 2.7 读/写 csv 文件(我的 csv)有疑问。标题是
['\xef\xbb\xbfID;timestamp;CustomerID;Email']
我从文件A.csv
中读取了一些代码("\xef\xbb\xbfID"
),我想将相同的代码和标题写入文件B.csv
我的打印日志显示:
['\xef\xbb\xbfID;timestamp;CustomerID;Email']
但是实际的输出文件头看起来像
ÔªøID;timestamp
代码如下:
def remove_gdpr_info_from_csv(file_path, file_name, temp_folder, original_header):
new_temp_folder = tempfile.mkdtemp()
new_temp_file = new_temp_folder + "/" + file_name
# Blanked new file
with open(new_temp_file, 'wb') as outfile:
writer = csv.writer(outfile, delimiter=";")
print original_header
writer.writerow(original_header)
# File from SFTP
with open(file_path, 'r') as infile:
reader = csv.reader(infile, delimiter=";")
first_row = next(reader)
email = first_row.index('Email')
contract_detractor1 = first_row.index('Contact Detractor (Q21)')
contract_detractor2 = first_row.index('Contact Detractor (Q20)')
contract_detractor3 = first_row.index('Contact Detractor (Q43)')
contract_detractor4 = first_row.index('Contact Detractor(Q26)')
contract_detractor5 = first_row.index('Contact Detractor(Q27)')
contract_detractor6 = first_row.index('Contact Detractor(Q44)')
indexes = []
for column_name in header_list:
ind = first_row.index(column_name)
indexes.append(ind)
for row in reader:
output_row = []
for ind in indexes:
data = row[ind]
if ind == email:
data = ''
elif ind == contract_detractor1:
data = ''
elif ind == contract_detractor2:
data = ''
elif ind == contract_detractor3:
data = ''
elif ind == contract_detractor4:
data = ''
elif ind == contract_detractor5:
data = ''
elif ind == contract_detractor6:
data = ''
output_row.append(data)
writer.writerow(output_row)
s3core.upload_files(SPARKY_S3, DESTINATION_PATH, new_temp_file)
shutil.rmtree(temp_folder)
shutil.rmtree(new_temp_folder)
【问题讨论】:
【参考方案1】:'\xef\xbb\xbf'
是 Unicode ZERO WIDTH NO-BREAK SPACE U+FEFF 的 UTF8 编码版本。它通常用作 unicode 文本文件开头的字节顺序标记:
'\xef\xbb\xbf'
,那么文件是 utf8 编码的
当你有 2 个字节时:'\xff\xfe'
,那么文件是 utf16 little endian
当你有2个字节时:'\xfe\xff'
,那么文件是utf16 big endian
'utf-8-sig'
编码明确要求在文件开头写入此 BOM
要在 Python 2 中读取 csv 文件时自动处理它,您可以使用 codecs 模块:
with open(file_path, 'r') as infile:
reader = csv.reader(codecs.EncodedFile(infile, 'utf8-sig', 'utf8'), delimiter=";")
EncodedFile
将通过在utf8-sig
中解码来包装原始文件对象,实际上跳过了 BOM 并在 utf8
中重新编码,没有 BOM。
【讨论】:
嗨,Serge,谢谢你的建议,我试过了,还是一样的问题。我想知道这个问题是否是因为 writer.writerow(original_header),original_header 是一个列表。 顺便问一下如果有\xef\xbb\xbf\xef\xbb\xbf这是什么代码? @SharpLu:如果你有两倍的 utf8 BOM,那么文件在 utf8-sig 中被错误编码了两次。 谢谢,问题已解决。 @SergeBallesta,看起来EncodedFile
中的参数颠倒了。应该是这样吗? codecs.EncodedFile(infile, 'utf-8', 'utf-8-sig')
?【参考方案2】:
您想使用 codecs
库中的 EncodedFile
方法,如 Serge Ballesta 的回答。
但是使用 Python 2.7 编码 utf-8-sig
不是 UTF8-sig 编码支持的别名,您需要使用 utf_8_sig
。另外方法属性的顺序需要先定义输出数据编码,再定义文件编码:codecs.EncodedFile(file,datacodec,filecodec=None,errors=’strict')
这是完整的结果:
import codecs
with open(file_path, 'r') as infile:
reader = csv.reader(codecs.EncodedFile(infile, 'utf8', 'utf_8_sig'), delimiter=";")
【讨论】:
以上是关于Python 2.7 CSV 文件读/写 \xef\xbb\xbf 代码的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 中编写适用于 Windows 中的 Python 2.7+ 和 Python 3.3+ 的 .CSV 文件