“UnicodeEncodeError:‘ascii’编解码器无法编码字符”

Posted

技术标签:

【中文标题】“UnicodeEncodeError:‘ascii’编解码器无法编码字符”【英文标题】:"UnicodeEncodeError: 'ascii' codec can't encode character" 【发布时间】:2010-12-11 19:03:38 【问题描述】:

我正在尝试通过正则表达式传递大量随机 html 字符串,而我的 Python 2.6 脚本对此感到窒息:

UnicodeEncodeError: 'ascii' 编解码器无法编码字符

我追溯到这个词末尾的商标上标: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()

【问题讨论】:

请发布python版本,以及作为异常一部分的回溯。 您使用的是哪个版本的 Python? Python 的 Unicode 支持在最近几个版本中有了很大的发展。 这里是版本:Python 2.6 谢谢! 【参考方案1】:

您正在尝试在“严格”模式下将 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

【讨论】:

感谢您的努力——我更新了我的问题,并将尝试使其与您的信息一起使用。 -KBF1【参考方案2】:

您正试图将一个字节串传递给某物,但不可能(由于您提供的信息稀缺)告诉 您试图将它传递给什么。您从一个无法编码为 ASCII(默认编解码器)的 Unicode 字符串开始,因此,您必须使用一些不同的编解码器进行编码(或按照@R.Pate 的建议对其进行音译)——但这不可能用于说您应该使用 what 编解码器,因为我们不知道您传递的字节串是什么,因此不知道未知子系统将能够接受和正确处理什么编解码器。

在您离开我们的黑暗中,utf-8 是一个合理的盲目猜测(因为它是一个可以将任何 Unicode 字符串完全表示为字节串的编解码器,并且它是用于许多用途的标准编解码器,例如 XML) -- 但这只不过是一种盲目的猜测,除非你要告诉我们更多关于 what 你试图将该字节串传递给的信息,以及用于什么目的。

传递thestring.encode('utf-8') 而不是裸露的thestring 肯定会避免您现在看到的特定错误,但它可能会导致奇怪的显示(或您尝试的任何处理那个字节串!)除非接收者准备好,愿意并且能够接受 utf-8 编码(我们怎么知道,对接收者可能是什么完全零概念?!-)

【讨论】:

根据您的笔记更新了信息,我现在将开始研究如何使用 utf-8 -- 谢谢! 所以,现在我们知道您的错误是在写入文件时出现的 - 迁移到 utf-8 肯定会解决这个问题……但是什么时候再次读回文件以及它是如何处理的呢?我们仍然完全不知道您的 unicode -> 字节串转换的真正目的!-) 提供了完整的脚本=也欢迎一般建议。谢谢!【参考方案3】:

“最佳”方式始终取决于您的要求;那么,你的呢?忽略非ASCII合适吗?你应该用“(tm)”替换™吗? (这个例子看起来很花哨,但对于其他代码点来说很快就崩溃了——但它可能正是你想要的。)这个异常是否正是你所需要的?现在你只需要以某种方式处理它?

只有你才能真正回答这个问题。

【讨论】:

【参考方案4】:

首先,尝试安装英语翻译(或任何其他,如果需要):

sudo apt-get install language-pack-en

它为所有受支持的包(包括 Python)提供翻译数据更新。

并确保在代码中使用正确的编码。

例如:

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

然后仔细检查您的系统配置,例如 LANG 的值或区域设置 (/etc/default/locale) 的配置,不要忘记重新登录会话。

【讨论】:

以上是关于“UnicodeEncodeError:‘ascii’编解码器无法编码字符”的主要内容,如果未能解决你的问题,请参考以下文章