Python的urllib中的网页的Unicode问题

时间:2009-06-29 13:27:42

标签: python unicode

我似乎有一个熟悉的正确阅读和查看网页的问题。看起来Python以UTF-8读取页面但是当我尝试将其转换为更易于查看的内容时(iso-8859-1)我收到此错误:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 2: ordinal not in range(128)

代码如下所示:

#!/usr/bin/python
from urllib import urlopen
import re

url_address = 'http://www.eurohockey.net/players/show_player.cgi?serial=4722'

finished = 0
begin_record = 0
col = 0
str = ''

for line in urlopen(url_address):
    if '</tr' in line:
        begin_record = 0                   
        print str
        str = ''
        continue

    if begin_record == 1:
        col = col + 1
        tmp_match =  re.search('<td>(.+)</td>', line.strip())
        str = str + ';' + unicode(tmp_match.group(1), 'iso-8859-1')

    if '<tr class=\"even\"' in line or '<tr class=\"odd\"' in line: 
        begin_record = 1
        col = 0
        continue

我该如何处理内容? Firefox至少认为它是iso-8859-1,看看该页面的内容是有意义的。错误来自'ä'字符。

如果我要将数据保存到数据库中,我是否应该在更改编解码器然后在显示时进行转换?

3 个答案:

答案 0 :(得分:3)

正如Lennart所说,你的问题不是解码。它试图编码为“ascii”,这通常是print语句的问题。我怀疑这条线

print str

是你的问题。您需要将str编码为控制台用于使该行工作的任何内容。

答案 1 :(得分:2)

看起来Python根本就不是“用UTF-8读取它”。正如已经指出的,你有编码问题,而不是解码问题。你说的那条线是不可能出现这种错误的。在提出这样的问题时,请始终提供完整的追溯和错误消息。

凯西的怀疑是正确的;实际上print str行是该错误的唯一可能来源,并且只有在未设置sys.stdout.encoding时才会发生这种情况,因此Python会在'ascii'上发布。

可能影响结果的变量是您正在使用的Python版本,您正在运行的平台以及您运行脚本的确切方式 - 您没有告诉我们这些;请做。

示例:我在Windows XP上使用Python 2.6.2并且我正在运行带有一些诊断添加的脚本: (1)import sys; print sys.stdout.encoding靠近前方 (2)在print repr(str)之前print str,以便在崩溃之前我能看到你所拥有的东西。

在“命令提示符”窗口中,如果我执行\python26\python hockey.py,则会将cp850作为编码进行打印,然后才能正常工作。

但是,如果我这样做

\python26\python hockey.py | more

\python26\python hockey.py >hockey.txt

它打印None作为编码,并在第一行使用a-with-diaeresis与您的错误消息崩溃:

C:\junk>\python26\python hockey.py >hockey.txt
Traceback (most recent call last):
  File "hockey.py", line 18, in <module>
    print str
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 2: ordinal not in range(128)

如果符合您的情况,通常的修复方法是使用适合您计划使用的显示机制的编码对输出进行显式编码。

答案 2 :(得分:1)

该文本确实是iso-88591-1,我可以毫无问题地对其进行解码,实际上您的代码运行顺利。

但是,您的错误是ENCODE错误,而不是解码错误。并且您不在代码中进行任何编码,因此。可能你的编码和解码很困惑,这是一个常见的问题。

您从Latin1解码为Unicode。你以另一种方式编码。请记住,Latin1,UTF8等称为“编码”。