2011-01-25 2 views
12

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

Я попытался с помощью chardet для определения кодировки и преобразовать в ascii или utf-8docs, кажется, не сказать, что это должно быть). допустимая потеря, но в то время как линии декодирования/кодирования работают очень хорошо, я всегда получаю сообщение об ошибке после 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) 

ответ

17

Это действительно 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

Какое кодирование делает chardet сказать, что это?

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

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

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

+0

код, который я написал, содержит образец URL. chardet говорит, что пример url - utf-8, но при использовании этой программы встречаются другие кодировки (все они дают одну и ту же ошибку Unicode). Я могу прочитать его, и это имеет смысл, когда он печатает на моей консоли. Ubuntu 10.10 - это моя ОС. У меня нет аргументов в пользу декодирования/кодирования. Я изо всех сил пытаюсь понять это, и нашел множество противоречивых предложений через google, что является одним из них дословным (я не помню, откуда). Благодарю вас за помощь. Постскриптум 'Page.decode ('UTF-8'); self.feed (page) 'дает ту же ошибку. –

+0

Чтобы уточнить, вы пробовали 'page = page.decode ('utf-8'); self.feed (страница) '? – William

+0

да, у меня есть такая же ошибка: 'UnicodeDecodeError: 'ascii' codec не может декодировать байт 0xc3 в позиции 16688: порядковый номер не в диапазоне (128)' –