Python HTMLParser: Unicode解码错误

12 投票
2 回答
14110 浏览
提问于 2025-04-16 10:34

我正在使用HTMLParser来解析通过urllib下载的网页,但在将某些内容传递给HTMLParser时,遇到了UnicodeDecodeError的错误。

我尝试使用chardet来检测编码,并转换成asciiutf-8文档似乎没有说明应该是什么编码)。虽然可以接受一些信息的丢失,但在解码和编码的过程都没有问题,但每次调用self.feed()后,我总是会遇到这个错误。

如果我直接print出来,信息是可以正常显示的。

from HTMLParser import HTMLParser
import urllib
import chardet

class search_youtube(HTMLParser):

    def __init__(self, search_terms):
        HTMLParser.__init__(self)
        self.track_ids = []
        for search in search_terms:
            self.__in_result = False
            search = urllib.quote_plus(search)
            query = 'http://youtube.com/results?search_query='
            page = urllib.urlopen(query + search).read()
            try:
                self.feed(page)
            except UnicodeDecodeError:
                encoding = chardet.detect(page)['encoding']
                if encoding != 'unicode':
                    page = page.decode(encoding)
                    page = page.encode('ascii', 'ignore')
                self.feed(page)
                print 'success'

searches = ['telepopmusik breathe']
results = search_youtube(searches)
print results.track_ids

这是输出结果:

Traceback (most recent call last):
  File "test.py", line 27, in <module>
    results = search_youtube(searches)
  File "test.py", line 23, in __init__
    self.feed(page)
  File "/usr/lib/python2.6/HTMLParser.py", line 108, in feed
    self.goahead(0)
  File "/usr/lib/python2.6/HTMLParser.py", line 148, in goahead
    k = self.parse_starttag(i)
  File "/usr/lib/python2.6/HTMLParser.py", line 252, in parse_starttag
    attrvalue = self.unescape(attrvalue)
  File "/usr/lib/python2.6/HTMLParser.py", line 390, in unescape
    return re.sub(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));", replaceEntities, s)
  File "/usr/lib/python2.6/re.py", line 151, in sub
    return _compile(pattern, 0).sub(repl, string, count)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

2 个回答

1

chardet说它是什么编码?

请解释一下“如果我把它打印出来,信息就在那里”:这里的“它”指的是什么?如果你能读懂它,并且在控制台打印出来时也能理解,那么它一定是你系统的常用编码;那是什么呢?你用的是什么操作系统?地区设置是什么?

你能给我们一个典型的URL吗?这样我们可以自己查看你看到的内容。

在你代码的某个地方,你先解码了输出,然后立刻用.encode('ascii', 'ignore')把它搞坏;这是为什么呢?

18

确实是UTF-8编码。这个方法可以用:

from HTMLParser import HTMLParser
import urllib

class search_youtube(HTMLParser):

    def __init__(self, search_terms):
        HTMLParser.__init__(self)
        self.track_ids = []
        for search in search_terms:
            self.__in_result = False
            search = urllib.quote_plus(search)
            query = 'http://youtube.com/results?search_query='
            connection = urllib.urlopen(query + search)
            encoding = connection.headers.getparam('charset')
            page = connection.read().decode(encoding)
            self.feed(page)
            print 'success'

searches = ['telepopmusik breathe']
results = search_youtube(searches)
print results.track_ids

你不需要用chardet这个工具,YouTube可不是傻瓜,他们在头部信息里其实已经发送了正确的编码。

撰写回答