Python HTMLParser: UnicodeDecodeError - PullRequest
       16

Python HTMLParser: UnicodeDecodeError

12 голосов
/ 25 января 2011

Я использую HTMLParser для анализа страниц, которые я опускаю с помощью urllib, и сталкиваюсь с UnicodeDecodeError исключениями при передаче некоторых в HTMLParser.

Я пытался использовать chardet, чтобы обнаружить кодировки и преобразовать в ascii или utf-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 ]

17 голосов
/ 25 января 2011

Это действительно 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 не дебилы, они действительно посылают правильную кодировку в шапке.

1 голос
/ 25 января 2011

В какой кодировке написано chardet?

Пожалуйста, объясните "Информация есть, если я просто распечатаю ее": что такое "это"? Если вы можете прочитать его, и это имеет смысл, когда вы печатаете его на своей консоли, тогда он должен быть в обычной / стандартной кодировке для вашей системы; что это такое? Какая операционная система? Какая локаль?

Можете ли вы дать нам типичный URL-адрес для запроса, чтобы мы сами могли проверить, что вы видите?

В одном месте вашего кода вы декодируете свои выходные данные, а затем сразу же разбиваете их, используя .encode('ascii', 'ignore'); почему?

...