Python, Docker - 'ascii'编解码器无法编码字符

25

我写了一个使用Python3进行网页抓取并将一些信息存储到CSV文件中的脚本。这个脚本在我的电脑上运行良好。但是当我尝试在Docker容器中运行该脚本时,出现了问题。错误似乎出现在代码的这一部分(为了这个问题的目的而进一步简化)。

# default CSV module
import csv

# this is how an ACTUAL row looks like in my program, included it in case it was important
row = {'title': 'Electrochemical sensor for the determination of dopamine in presence of high concentration of ascorbic acid using a Fullerene-C60 coated gold electrode', 'url': 'https://onlinelibrary.wiley.com/doi/abs/10.1002/elan.200704073', 'author': 'Goyal, Rajendra Nath and Gupta, Vinod Kumar and Bachheti, Neeta and Sharma, Ram Avatar', 'abstract': 'A fullerene‐C60‐modified gold electrode is employed for the determination of dopamine in the excess of ascorbic acid using square‐wave voltammetry. Based on its strong catalytic function towards the oxidation of dopamine and ascorbic acid, the overlapping voltammetric …', 'eprint': 'http://www.academia.edu/download/3909892/Dopamene.pdf', 'publisher': 'Wiley Online Library', 'year': '2008', 'pages': '757--764', 'number': '7', 'volume': '20', 'journal': 'Electroanalysis: An International Journal Devoted to Fundamental and Practical Aspects of Electroanalysis', 'ENTRYTYPE': 'article', 'ID': 'goyal2008electrochemical'}

# the CSV writer object
writer = csv.DictWriter("file.csv", fieldnames=[a, b, c],  dialect='toMYSQL')

# this is the source of the problem!
writer.writerow(row)

我了解容器只有最基本的功能,这意味着脚本使用的编码可能不被支持。因此,在我的脚本开头添加了以下内容(在通常的 she-bang 下方):

# coding=utf-8

这些是我 Docker 上的本地化设置:

$ locale -a

C
C.UTF-8
POSIX
en_US.utf8
es_CR.utf8

我在电脑上还有更多的内容,但这不应该有太大影响,因为en_US.utf8涵盖了所有英语内容,es_CR.utf8涵盖了所有西班牙语内容。(如果不是全部,那么我的大部分结果都是英语。)

我正在使用Python3,所以我知道所有字符串都是Unicode字符,也许这与问题有关?

$ python3 --version
Python 3.6.5

尽管如此,当我运行程序时,脚本尝试在控制台打印行时,我会立即收到以下错误消息:
Exception in thread Thread-6:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/Systematic-Mapping-Engine/sysmapengine/scraper.py", line 100, in build_csv
    writer.writerow(clean_row)
  File "/usr/lib/python3.6/csv.py", line 155, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
UnicodeEncodeError: 'ascii' codec can't encode character '\u2010' in position 262: ordinal not in range(128)

7
这个问题似乎不是与链接问题重复的,因此上面的通知似乎是误导性的。在另一个问题中,问题并不是由于使用Docker环境而引起的,它的答案也无法解决该问题。 这里的问题不是某个随机文件具有不正确的编码并需要特殊处理,而是由于某些映像默认值,Docker容器中的任何文件都被假定为具有错误的编码。如果包括Dockerfile或镜像名称,并展示原始Python的“open”而非“csv”模块,将有助于改进此问题。 - pkubik
2
这个问题绝对不是重复的,我们如何取消标记? - Vincent Buscarello
1
投票重新开放;这绝对不是重复的。 - Clément
1个回答

40

大多数容器启动时都使用LANG=C设置。如果你要处理UTF-8,这可能非常麻烦。

为确保容器以正确的区域设置启动,请在调用docker时添加-e LANG=C.UTF-8


14
Dockerfile 中的一行命令:ENV LANG C.UTF-8。意思是设置环境变量 LANG 为 C.UTF-8。 - Rexcirus

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