Python Unicodeエンコードエラー


104

Amazon XMLファイルを読み取って解析していますが、XMLファイルに 'が表示されているのに、印刷しようとすると次のエラーが発生します。

'ascii' codec can't encode character u'\u2019' in position 16: ordinal not in range(128) 

これまでオンラインで読んだことから、エラーはXMLファイルがUTF-8であるという事実に起因していますが、PythonはそれをASCIIエンコード文字として処理したいと考えています。エラーをなくし、プログラムがXMLを読み取るときにXMLを印刷する簡単な方法はありますか?


私はちょうどこの質問を投稿するためにSOに来ていました。文字列をサニタイズする簡単な方法はありunicode()ますか?
Nick Heiner

関連する質問に対するこの回答も確認してください:「Python UnicodeDecodeError-エンコードを誤解していますか?」
tzot 2010

回答:


193

おそらく、あなたの問題はあなたがそれを大丈夫に解析したことであり、そして今あなたはXMLの内容を印刷しようとしているのですが、いくつかの外国のUnicode文字があるためにそれができません。最初にあなたのユニコード文字列をアスキーとしてエンコードしてみてください:

unicodeData.encode('ascii', 'ignore')

「無視」の部分は、それらの文字をスキップするように指示します。Pythonドキュメントから:

>>> u = unichr(40960) + u'abcd' + unichr(1972)
>>> u.encode('utf-8')
'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
'abcd'
>>> u.encode('ascii', 'replace')
'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
'&#40960;abcd&#1972;'

:あなたはこの記事読みたいかもしれませんhttp://www.joelonsoftware.com/articles/Unicode.html、私は何が起こっている上の基本的なチュートリアルとして非常に有用であることが判明しました。読んだ後は、どのコマンドを使用するかを推測しているように感じることはなくなります(または少なくともそれが私に起こりました)。


1
私は次の文字列を安全にしようとしています: 'foo“ bar bar” df'(中かっこに注意)でも、上記の方法ではうまくいきません。
Nick Heiner、2010

@Rosarch:どのように失敗しますか?同じエラー?そして、どのエラー処理ルールを使用しましたか?
スコットスタッフォード

@Rosarch、あなたの問題はおそらくもっと早いです。# - :このコードを試してみてください-コーディング:ラテン-1 - - U = U「foo 『というバーバー』 DF」印刷u.encode( 『ASCII』、 『無視』)あなたのために、それはおそらく与えられたユニコードにあなたの文字列を変換したがエラーをスローしたpython scripに指定したエンコーディング。
スコットスタッフォード

私は先に行って、独自の質問に私の問題を作った:stackoverflow.com/questions/3224427/...
ニック・ハイナー

1
.encode('ascii', 'ignore')OPの環境が非ASCII文字をサポートしている場合でも(ほとんどの場合)、データが不必要に失われる
jfs

16

より良いソリューション:

if type(value) == str:
    # Ignore errors even if the string is not proper UTF-8 or has
    # broken marker bytes.
    # Python built-in function unicode() can do this.
    value = unicode(value, "utf-8", errors="ignore")
else:
    # Assume the value object has proper __unicode__() method
    value = unicode(value)

理由についてもっと知りたい場合:

http://docs.plone.org/manage/troubleshooting/unicode.html#id1


3
OPの問題「文字u '\ u2019'をエンコードできません」には役立ちません。u'\u2019すでにユニコードです。
jfs

6

スクリプト内に環境の文字エンコードをハードコーディングしないでください。代わりに、Unicodeテキストを直接印刷します。

assert isinstance(text, unicode) # or str on Python 3
print(text)

出力がファイル(またはパイプ)にリダイレクトされる場合。PYTHONIOENCODINGenvvarを使用して、文字エンコーディングを指定できます。

$ PYTHONIOENCODING=utf-8 python your_script.py >output.utf8

それ以外の場合は、python your_script.pyそのまま機能するはずです-ロケール設定を使用してテキストをエンコードします(POSIXチェックLC_ALLLC_CTYPELANG、、、envvars-セットLANG必要に応じてutf-8ロケールにします)。

WindowsでUnicodeを印刷するには、Windowsコンソール、ファイル、またはIDLEを使用してUnicodeを印刷する方法を示すこの回答を参照してください


1

優れた投稿:http : //www.carlosble.com/2010/12/understanding-python-and-unicode/

# -*- coding: utf-8 -*-

def __if_number_get_string(number):
    converted_str = number
    if isinstance(number, int) or \
            isinstance(number, float):
        converted_str = str(number)
    return converted_str


def get_unicode(strOrUnicode, encoding='utf-8'):
    strOrUnicode = __if_number_get_string(strOrUnicode)
    if isinstance(strOrUnicode, unicode):
        return strOrUnicode
    return unicode(strOrUnicode, encoding, errors='ignore')


def get_string(strOrUnicode, encoding='utf-8'):
    strOrUnicode = __if_number_get_string(strOrUnicode)
    if isinstance(strOrUnicode, unicode):
        return strOrUnicode.encode(encoding)
    return strOrUnicode

0

あなたは形の何かを使うことができます

s.decode('utf-8')

これは、UTF-8でエンコードされたバイト文字列をPython Unicode文字列に変換します。ただし、使用する正確な手順は、XMLファイルをロードして解析する方法によって異なります。たとえば、XML文字列に直接アクセスしない場合は、codecsモジュールのデコーダーオブジェクトを使用する必要があります


それはすでにUTF-8でエンコードされていますエラーは具体的には:myStrings = deque([u'Dorf and Svoboda \ u2019s text builds on the str ... and Computer Engineering \ u2019s subdisciplines。 '])文字列はUTF-8としてあなたは見ることができますが、内部の '\ u2019'に腹を立てています
Alex B

ああ、わかりました。別の問題が発生していると思いました。
David Z

7
@アレックスB:いいえ、文字列はUtf-8ではなくUnicodeです。するために、エンコード UTF-8の使用としてそれを'...'.encode('utf-8')
かなっ

0

迷惑な非ASCII引用符を修正し、変換を使用可能なものに強制するために、以下を書きました。

unicodeToAsciiMap = {u'\u2019':"'", u'\u2018':"`", }

def unicodeToAscii(inStr):
    try:
        return str(inStr)
    except:
        pass
    outStr = ""
    for i in inStr:
        try:
            outStr = outStr + str(i)
        except:
            if unicodeToAsciiMap.has_key(i):
                outStr = outStr + unicodeToAsciiMap[i]
            else:
                try:
                    print "unicodeToAscii: add to map:", i, repr(i), "(encoded as _)"
                except:
                    print "unicodeToAscii: unknown code (encoded as _)", repr(i)
                outStr = outStr + "_"
    return outStr

0

これらの印刷できない文字を無視するのではなく、文字列のおおよその表現を画面に印刷する必要がある場合は、こちらのunidecodeパッケージを試してください。

https://pypi.python.org/pypi/Unidecode

説明はここにあります:

https://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/

これはu.encode('ascii', 'ignore')、指定された文字列uにfor を使用するよりも優れており、文字の精度が希望どおりではないが、人間が読みやすくしたい場合に、不必要な頭痛からあなたを救うことができます。

ウィラワン


-1

Pythonスクリプトの先頭に次の行を追加してみてください。

# _*_ coding:utf-8 _*_

-1

Python 3.5、2018

エンコーディングがわからないが、Unicodeパーサーに問題がある場合はNotepad++、上部のバーでファイルを開き、を選択しますEncoding->Convert to ANSI。それから、あなたはこのようにあなたのpythonを書くことができます

with open('filepath', 'r', encoding='ANSI') as file:
    for word in file.read().split():
        print(word)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.