2

utf-8 文字列を含む辞書を CSV に書き込もうとしています。ここからの指示に従っています。ただし、これらの utf-8 文字列を細心の注意を払ってエンコードおよびデコードしているにもかかわらず、「ascii」セットに関連する UnicodeEncodeErrors が発生しています。

ウィキペディアの記事の変更に関連する値として文字列と整数を含む辞書のリストがあります。以下のリストは、この変更に対応しています。例:

edgelist = [{'articleName': 'Barack Obama', 'editorName': 'Schonbrunn', 'revID': '121844749', 'bytesAdded': '183'}, 
{'articleName': 'Barack Obama', 'editorName': 'Eep\xc2\xb2', 'revID': '121862749', 'bytesAdded': '107'}]

問題はlist[1]['editorName']. タイプが'str'あり、el[1]['editorName'].decode('utf-8')u'Eep\xb2'

私が試みているコードは次のとおりです。

_ENCODING = 'utf-8'
def dictToCSV(edgelist,output_file):
    with codecs.open(output_file,'wb',encoding=_ENCODING) as f:
        w = csv.DictWriter(f,sorted(edgelist[0].keys()))
        w.writeheader()
        for d in edgelist:
            for k,v in d.items():
                if type(v) == int:
                    d[k]=str(v).encode(_ENCODING)
            w.writerow({k:v.decode(_ENCODING) for k,v in d.items()})

これは以下を返します:

dictToCSV(edgelist,'test2.csv')
File "csv_to_charts.py", line 129, in dictToCSV
w.writerow({k:v.decode(_ENCODING,'ignore') for k,v in d.items()})
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 148, in writerow
return self.writer.writerow(self._dict_to_list(rowdict))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb2' in position 3: ordinal not in range(128)

デコードをエンコードに交換したり、最終的な問題のある行に何もないなどの他の順列もエラーを返します。

  1. w.writerow({k:v.encode(_ENCODING) for k,v in d.items()})戻り値'UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 56: ordinal not in range(128)
  2. w.writerow({k:v for k,v in d.items()})戻り値UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 56: ordinal not in range(128)
  3. これに続いて、に変更with codecs.open(output_file,'wb',encoding=_ENCODING) as f:with open(output_file,'wb') as f:ても同じエラーが発生します。

この問題のある文字列を含むリスト要素またはキーを除外すると、スクリプトは正常に動作します。

4

3 に答える 3

3

コードを次のように編集したところ、csv が正常に書き込まれました。

from django.utils.encoding import smart_str
import csv

def dictToCSV(edgelist, output_file):
    f = open(output_file, 'wb')
    w = csv.DictWriter(f, fieldnames=sorted(edgelist[0].keys()))
    w.writeheader()
    for d in edgelist:
        w.writerow(dict(k=smart_str(v)) for k, v in d.items())
    f.close()

Django コードをコピーして、必要に応じてカスタマイズします。

于 2012-08-03T18:05:44.837 に答える
0

ASCIIエンコーディングの厳密な解釈では、序数0〜127のみが許可されます。その範囲外の値は、定義上ASCIIではありません。\xc2と\xb2はどちらも127より大きい序数を持っているため、ASCIIとして解釈することはできません。

私はPythonユーザーではありません。CSVのRFCは、一般的な使用法としてASCIIに言及していますが、MIMEタイプのオプションの「charset」パラメーターを定義しています。使用しているライターにも「エンコード」設定があるのではないでしょうか。

于 2012-08-03T17:56:30.970 に答える
0

文字列はすでにUTF-8にあり、DictWriterはで動作しませんcodecs.openその例に従う:

# coding: utf-8
import csv

edgelist = [
    {'articleName': 'Barack Obama', 'editorName': 'Schonbrunn', 'revID': '121844749', 'bytesAdded': '183'},
    {'articleName': 'Barack Obama', 'editorName': 'Eep\xc2\xb2', 'revID': '121862749', 'bytesAdded': '107'}]

with open('out.csv','wb') as f:
    f.write(u'\ufeff'.encode('utf8')) # BOM (optional...Excel needs it to open UTF-8 file properly)
    w = csv.DictWriter(f,sorted(edgelist[0].keys()))
    w.writeheader()
    for d in edgelist:
        w.writerow(d)

出力:

articleName,bytesAdded,editorName,revID
Barack Obama,183,Schonbrunn,121844749
Barack Obama,107,Eep²,121862749

'editorName': 'Eep²'の代わりに直接使用できることに注意してください'editorName': 'Eep\xc2\xb2'。バイト文字列は、とごとにUTF-8でエンコードされ# coding: utf-8、ソースファイルをUTF-8で保存します。

于 2012-08-04T00:43:46.823 に答える