Unicode编码错误:'ascii'编码无法编码位置0-1的字符:序号不在范围(128)内

5 投票
2 回答
7104 浏览
提问于 2025-04-20 03:24

我不太清楚这个错误的具体来源是什么,也不知道该怎么解决。我是在运行这段代码时遇到的这个问题。

 Traceback (most recent call last):
      File "t1.py", line 86, in <module>
        write_results(results)
      File "t1.py", line 34, in write_results
        dw.writerows(results)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 154, in writerows
        return self.writer.writerows(rows)
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

任何解释都非常感谢!

我修改了代码,现在出现了这个错误:

 File "t1.py", line 88, in <module>
    write_results(results)
  File "t1.py", line 35, in write_results
    dw.writerows(results)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 154, in writerows
    return self.writer.writerows(rows)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

这是我做的修改:

 with codecs.open('results.csv', 'wb', 'utf-8') as f:
        dw = csv.DictWriter(f, fieldnames=fields, delimiter='|')
        dw.writer.writerow(dw.fieldnames)
        dw.writerows(results)

2 个回答

0

这个应该可以正常运行。对我来说是有效的。代码片段如下:

import csv
import sys
reload(sys)
sys.setdefaultencoding('utf8')
data = [["a", "b", u'\xe9']]
with open("output.csv", "w") as csv_file:
    writer = csv.writer(csv_file, quoting=csv.QUOTE_ALL)
    writer.writerows(data)
4

这个错误是由代码的这一部分引起的:

with open('results.csv', 'w') as f:
    dw = csv.DictWriter(f, fieldnames=fields, delimiter='|')
    dw.writer.writerow(dw.fieldnames)
    dw.writerows(results)

你正在打开一个ASCII文件,然后试图往里面写入非ASCII的数据。我猜写这个脚本的人在测试的时候没有遇到过非ASCII字符,所以他没有碰到这个错误。

但是如果你查看一下csv模块的文档,你会发现这个模块无法正确处理Unicode字符串(也就是Beautiful Soup返回的内容),而且CSV文件必须以二进制模式打开,只有UTF-8或ASCII是安全的写入格式。

所以在写入之前,你需要把所有字符串编码成UTF-8。我最开始以为只在写的时候编码字符串就可以了,但Python 2的csv模块对Unicode字符串还是会出错。所以我想没有其他办法,只能明确地对每个字符串进行编码:

parse_results()中,把这一行改成

results.append({'url': url, 'create_date': create_date, 'title': title})

改成

results.append({'url': url, 'create_date': create_date, 'title': title.encode("utf-8")})

这样可能就足够了,因为我不认为网址或日期会包含非ASCII字符。

撰写回答