Python写入CSV时出现ASCII编解码器无法编码字符错误

12

我不太确定我需要怎么处理这个错误。我认为可能是需要添加 .encode('utf-8'),但我不确定是否正确,也不知道应该在哪里使用它。

错误信息如下:

line 40, in <module>
writer.writerows(list_of_rows)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 1
7: ordinal not in range(128)

这是我的Python脚本的基础。

import csv
from BeautifulSoup import BeautifulSoup

url = \
'https://dummysite'

response = requests.get(url)

html = response.content

soup = BeautifulSoup(html)

table = soup.find('table', {'class': 'table'})

list_of_rows = []
for row in table.findAll('tr')[1:]:
list_of_cells = []
for cell in row.findAll('td'):
    text = cell.text.replace('[','').replace(']','')
    list_of_cells.append(text)
list_of_rows.append(list_of_cells)

outfile = open("./test.csv", "wb")
writer = csv.writer(outfile)
writer.writerow(["Name", "Location"])
writer.writerows(list_of_rows)
3个回答

25

Python 2.x的CSV库存在问题。您有三个选项,按复杂度排序:

  1. 编辑:参见下文 使用修复后的库https://github.com/jdunck/python-unicodecsvpip install unicodecsv)。可作为插拔式替换 - 示例:

with open("myfile.csv", 'rb') as my_file:    
    r = unicodecsv.DictReader(my_file, encoding='utf-8')

  1. 阅读关于Unicode的CSV手册:https://docs.python.org/2/library/csv.html(请参考底部的示例)

  2. 手动将每个项目编码为UTF-8:

for cell in row.findAll('td'):
    text = cell.text.replace('[','').replace(']','')
    list_of_cells.append(text.encode("utf-8"))

编辑:我发现当读取UTF-16时,python-unicodecsv也存在问题。它会抱怨任何0x00字节。

相反,使用https://github.com/ryanhiebert/backports.csv,这更接近Python 3的实现并使用io模块。

安装:

pip install backports.csv

使用方法:

from backports import csv
import io

with io.open(filename, encoding='utf-8') as f:
    r = csv.reader(f):

哦,哇,我不知道 Python 中的 CSV 库有问题。非常感谢!这对我帮助很大。 - f00d
2
为什么这个问题没有得到足够的投票?我看到有人使用各种变通方法来解决这个问题,但老实说,没有哪一种方法比简单地使用“unicodecsv”模块更好。 - Marcello Grechi Lins

1
问题出在Python 2的csv库上。从unicodecsv 项目页面
Python 2的csv模块无法轻松处理Unicode字符串,导致可怕的“'ascii' codec can't encode characters in position ...”异常。
如果可以的话,只需安装unicodecsv。 pip install unicodecsv
import unicodecsv

writer = unicodecsv.writer(csvfile)
writer.writerow(row)

0

除了Alastair的卓越建议之外,我发现最简单的选择是使用Python3而不是Python2。在我的脚本中,它所需的只是将open语句中的wb更改为根据Python3的语法简单地写成w


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接