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

27
我正在尝试通过正则表达式传递大段随机的HTML文本,但我的Python 2.6脚本出现了问题:
UnicodeEncodeError: 'ascii' codec can't encode character 我追溯到这个单词结尾的商标上标: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版本以及异常中的回溯信息。 - gahooa
1
你正在使用哪个版本的Python?Python的Unicode支持在最近几个版本中得到了很大的发展。 - Daniel Pryden
这是版本:Python 2.6 谢谢! - KenBurnsFan1
4个回答

32

你正在尝试以“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

感谢你的努力——我已经更新了我的问题,并且会尝试使用你提供的信息解决它。-KBF1 - KenBurnsFan1

22
你正试图将一个字节串传递给某个东西,但是根据你提供的信息的缺乏,无法确定你正在尝试将其传递给什么。你以一个Unicode字符串开始,该字符串无法被编码为ASCII(默认编解码器),因此,你必须使用某个不同的编解码器进行编码(或者像@R.Pate建议的那样进行转换)——但是我们无法说出你应该使用哪种编解码器,因为我们不知道你正在传递字节串,因此不知道未知子系统将能够接受和处理哪种编解码器。
在我们处于如此彻底的黑暗之中时,'utf-8' 是一个合理的盲猜测(因为它是一种可以精确表示任何Unicode字符串的编码器,并且它是许多用途的标准编解码器,例如XML)——但是除非你将告诉我们更多关于你正在试图将那个字节串传递到什么地方以及为什么目的,否则它不能超出盲猜测的范围。
传递 `thestring.encode('utf-8')` 而不是裸露的 `thestring` 将绝对避免你现在看到的特定错误,但是它可能会导致奇怪的显示(或者是任何你试图对那个字节串做的事情!),除非接收者已经准备好,愿意并且能够接受 utf-8 编码(我们如何知道呢,因为我们对接收者可能的情况完全没有任何想法?!-)

根据您的笔记更新了信息,我现在会开始研究如何使用UTF-8 - 谢谢! - KenBurnsFan1
所以,现在我们知道你的错误是在写入文件时发生的 - 转换为 utf-8 一定会解决这个问题...但是文件何时被读取并且如何处理呢?我们仍然完全不了解你的 Unicode -> 字节串转换的真正目的!-) - Alex Martelli
提供完整脚本,欢迎提供一般性建议。谢谢! - KenBurnsFan1

1

“最佳”方法总是取决于你的需求;那么,你的需求是什么?忽略非ASCII字符是否合适?应该用“(tm)”替换™吗?(在这个例子中看起来很漂亮,但对于其他代码点来说可能会出错—但这可能正是你想要的。)异常是否恰好是你需要的;现在你只需要以某种方式处理它。

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


0

首先,尝试安装英语语言的翻译(或其他需要的语言):

sudo apt-get install language-pack-en

该软件提供所有支持的软件包(包括Python)的翻译数据更新。

请确保在您的代码中使用正确的编码方式。

例如:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接