web-dev-qa-db-ja.com

「UnicodeEncodeError: 'ascii'コーデックは文字をエンコードできません」

私は正規表現を介してランダムなHTMLの大きな文字列を渡そうとしています、そして私のPython 2.6スクリプトはこれで窒息しています:

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

私はそれをこのWord:Protection™の最後の商標の上付き文字にさかのぼって追跡します-将来、このような人に遭遇することを期待しています。

非ASCII文字を処理するモジュールはありますか?または、Pythonで非ASCIIのものを処理/エスケープするための最良の方法は何ですか?

ありがとう!完全なエラー:

E
======================================================================
ERROR: test_untitled (__main__.Untitled)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python26\Test2.py", line 26, in test_untitled
    ofile.write(Whois + '\n')
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 1005: ordinal not in range(128)

完全なスクリプト:

from Selenium import Selenium
import unittest, time, re, csv, logging

class Untitled(unittest.TestCase):
    def setUp(self):
        self.verificationErrors = []
        self.Selenium = Selenium("localhost", 4444, "*firefox", "http://www.BaseDomain.com/")
        self.Selenium.start()
        self.Selenium.set_timeout("90000")

    def test_untitled(self):
        sel = self.Selenium
        spamReader = csv.reader(open('SubDomainList.csv', 'rb'))
        for row in spamReader:
            sel.open(row[0])
            time.sleep(10)
            Test = sel.get_text("//html/body/div/table/tbody/tr/td/form/div/table/tbody/tr[7]/td")
            Test = Test.replace(",","")
            Test = Test.replace("\n", "")
            ofile = open('TestOut.csv', 'ab')
            ofile.write(Test + '\n')
            ofile.close()

    def tearDown(self):
        self.Selenium.stop()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()
27
KenBurnsFan1

バイトストリングを何かに渡そうとしていますが、(提供する情報が少ないため)whatを渡そうとしていることを伝えることは不可能です。 ASCII(デフォルトのコーデック))としてエンコードできないUnicode文字列で開始するため、いくつかの異なるコーデックでエンコードする(または@ R.Pateが示唆するように文字変換する)必要があります)-しかし、使用するコーデックをwhatと言うことは不可能です。バイト文字列を何を渡しているかがわからないため、コーデックに関して、その未知のサブシステムが何を正しく受け入れて処理できるかがわかりません。

あなたが私たちを残すような完全な闇の中では、_utf-8_は合理的なブラインド推測です(これは、任意のUnicode文字列をバイト文字列として正確に表すことができるコーデックであり、XMLなどの多くの目的のための標準のコーデックだからです)- -しかし、あなたがそのバイト文字列をどのような目的で渡そうとしているのかwhatについて詳しく説明するまで、それは盲目的な推測に過ぎません。

裸のthestringではなくthestring.encode('utf-8')を渡すと、現在表示されている特定のエラーを確実に回避できますが、奇妙な表示(またはそれが何であれis you 'そのバイト文字列でやろうとしている!)受信者が準備ができていない限り、utf-8エンコーディングを受け入れて受け入れることができます(そして、どのようにWE知っているか、受信者が何ができるかについてまったくまったく考えていません)たぶん?!-)

21
Alex Martelli

"strict"モードでUnicodeをASCIIに変換しようとしています:

>>> help(str.encode)
Help on method_descriptor:

encode(...)
    S.encode([encoding[,errors]]) -> object

    Encodes S using the codec registered for encoding. encoding defaults
    to the default encoding. errors may be given to set a different error
    handling scheme. Default is 'strict' meaning that encoding errors raise
    a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and
    'xmlcharrefreplace' as well as any other name registered with
    codecs.register_error that is able to handle UnicodeEncodeErrors.

おそらく、次のいずれかが必要です。

s = u'Protection™'

print s.encode('ascii', 'ignore')    # removes the ™
print s.encode('ascii', 'replace')   # replaces with ?
print s.encode('ascii','xmlcharrefreplace') # turn into xml entities
print s.encode('ascii', 'strict')    # throw UnicodeEncodeErrors
32
Seth

「最良の」方法は常に要件に依存します。それで、あなたは何ですか?非ASCIIを無視することは適切ですか? ™を「(tm)」に置き換えますか? (この例では空想に見えますが、すぐに他のコードポイントに分解されます—しかし、それはまさにあなたが望むものであるかもしれません。)例外はまさにあなたが必要とするものかもしれません。今、あなたはそれを何らかの方法で処理する必要がありますか?

この質問に本当に答えられるのはあなただけです。

1
Roger Pate

まず、英語(または必要に応じてその他)の翻訳をインストールしてみます。

Sudo apt-get install language-pack-en

サポートされているすべてのパッケージ(Pythonを含む)の翻訳データの更新を提供します。

また、コードで正しいエンコーディングを使用していることを確認してください。

例えば:

open(foo, encoding='utf-8')

次に、LANGの値やロケールの設定(/etc/default/locale)そして、セッションに再ログインすることを忘れないでください。

0
kenorb