web-dev-qa-db-ja.com

Python:UnicodeEncodeError: 'latin-1'コーデックは文字をエンコードできません

私はapiを呼び出し、apiの結果に基づいて、apiにある各レコードのデータベースを呼び出すシナリオにいます。私のAPI呼び出しは文字列を返し、APIによって返されるアイテムのデータベース呼び出しを行うと、一部の要素で次のエラーが発生します。

_Traceback (most recent call last):
  File "TopLevelCategories.py", line 267, in <module>
    cursor.execute(categoryQuery, {'title': startCategory});
  File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/cursors.py", line 158, in execute
    query = query % db.literal(args)
  File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/connections.py", line 265, in literal
    return self.escape(o, self.encoders)
  File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/connections.py", line 203, in unicode_literal
    return db.literal(u.encode(unicode_literal.charset))
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 3: ordinal not in range(256)
_

上記のエラーが参照している私のコードのセグメントは次のとおりです。

_         ...    
         for startCategory in value[0]:
            categoryResults = []
            try:
                categoryRow = ""
                baseCategoryTree[startCategory] = []
                #print categoryQuery % {'title': startCategory}; 
                cursor.execute(categoryQuery, {'title': startCategory}) #unicode issue
                done = False
                cont...
_

グーグル検索を行った後、コマンドラインで次のことを試して、何が起こっているのかを理解しました...

_>>> import sys
>>> u'\u2013'.encode('iso-8859-1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 0: ordinal not in range(256)
>>> u'\u2013'.encode('cp1252')
'\x96'
>>> '\u2013'.encode('cp1252')
'\\u2013'
>>> u'\u2013'.encode('cp1252')
'\x96'
_

しかし、私はこの問題を克服するための解決策が何であるかわかりません。また、encode('cp1252')の背後にある理論が何であるかわかりません。上記で試したことについて説明が得られれば、すばらしいと思います。

12
add-semi-colons

Latin-1エンコーディングが必要な場合は、255を超えるen-dashまたはその他のコードポイント(Latin-1に含まれていない文字)を削除するためのいくつかのオプションがあります。

>>> u = u'hello\u2013world'
>>> u.encode('latin-1', 'replace')    # replace it with a question mark
'hello?world'
>>> u.encode('latin-1', 'ignore')     # ignore it
'helloworld'

または、独自のカスタム交換を行います。

>>> u.replace(u'\u2013', '-').encode('latin-1')
'hello-world'

Latin-1を出力する必要がない場合は、UTF-8が一般的で好ましい選択肢です。これはW3Cによって推奨されており、すべてのUnicodeコードポイントを適切にエンコードします。

>>> u.encode('utf-8')
'hello\xe2\x80\x93world'
16

Unicode文字u '\ 02013'は「ダッシュ」です。これは、Windows-1252(cp1252)文字セット(エンコードx96)に含まれていますが、Latin-1(iso-8859-1)文字セットには含まれていません。 Windows-1252文字セットには、x80〜x9fの領域にさらにいくつかの文字が定義されており、その中にはダッシュが含まれています。

解決策は、Windows-1252やUTF-8などのLatin-1とは異なるターゲット文字セットを選択するか、ダッシュを単純な「-」に置き換えることです。

3
Cito

u.encode('utf-8')はそれをバイトに変換し、sys.stdout.buffer.write(bytes)を使用してstdoutに出力できます https://docs.python.org/3/library/sys)のdisplayhookをチェックアウトします。 html

1
PriyankaP