我使用python2.7.3和BeuatofulSoup从网站的表中获取数据,然后使用codecs
将内容写入文件。我收集的一个变量中,偶尔会有乱码。例如,如果website表如下所示
Year Name City State
2000 John D’Iberville MS
2001 Steve Arlington VA
因此,当我生成City
变量时,我总是将其编码为utf-8
:
因此,我创建的名为RowData
和RowHeaders
的逗号分隔字符串列表的内容如下所示
RowHeaders = ['Year,Name,City,State']
RowsData = ['2000, John, D\xc3\xa2\xe2\x82\xac\xe2\x84\xa2Iberville, MS',
'2001, Steve, Arlington, VA']
然后我尝试用下面的代码将这个文件写入一个文件
file1 = codecs.open(Outfile.csv,"wb","utf8")
file1.write(RowHeaders + u'\n')
line = "\n".join(RowsData)
file1.write(line + u'\r\n')
file1.close()
我得到以下错误
Traceback (most recent call last):
File "HSRecruitsFBByPosition.py", line 141, in <module>
file1.write(line + u'\r\n')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 6879: ordinal not in range(128)
我可以在RowsData
上使用csv writer包,它工作得很好。出于我不想进入的原因,我需要使用编解码器来输出csv文件。我搞不清发生了什么事。有人能帮我解决这个问题吗?提前谢谢。在
codecs.open()
为您编码。不要把编码过的数据交给它,因为Python会再次尝试将数据解码为UTF-8。隐式解码使用ASCII编解码器,但由于编码字节字符串中有非ASCII数据,因此无法执行以下操作:解决方案是*不手动编码:
^{pr2}$请注意,} instead ;它提供了相同的功能,但实现得更健壮。
codecs.open()
不是文件流的最有效实现。在Python2.7中,我将使用^{io
模块是Python3的默认I/O实现,但在Python2中也提供了向前兼容性。在但是,您似乎在重新发明CSV处理;Python有一个优秀的^{} module ,可以为您生成CSV文件。但是,在Python 2中,它无法处理Unicode,因此需要手动编码:
最后但并非最不重要的是,如果您的HTML页面生成了文本
D’Iberville
,那么您生成了一个Mojibake;其中您将UTF-8误解为CP-1252:这通常是由于绕过BeautifulGroup的编码检测(传入字节字符串,而不是Unicode)引起的。在
你可以尝试在事后用以下方法“修复”这些问题:
这个
'D\xc3\xa2\xe2\x82\xac\xe2\x84\xa2Iberville'
是一个普通的字符串,它碰巧有表示字符的转义位。在你需要先把它解码。由于您还没有给出解码,Python正在尝试ASCII并失败。在
以下是如何理解这个过程:
首先,要明白字符是人类的,字节是计算机的。计算机只是帮我们把字节转换成字符,这样我们就可以理解数据了。
所以,任何时候你需要为计算机存储一些东西,你需要把它从字符转换成字节,因为这是计算机知道的。所有文件(甚至文本文件)都是字节。只要你打开它,就可以把这个字节数据转换成字符,这样我们就可以理解它的内容了。对于“二进制”文件(如图像或Word文档),这个过程有点不同。
如果我们正在写“文本”内容,我们需要获取glyphs(字符)并将它们转换成字节,以便可以写入文件。这个过程叫做解码。
当我们想“读”一个文本文件,也就是把字节转换成字形(字符或字母表)时,我们需要对这些位进行编码——实际上,翻译它们。为了知道哪个glyph对应于存储的位,我们使用一个查找表这个表名(utf-8)就是您传入的。
相关问题 更多 >
编程相关推荐