2011-01-25 15 views
12

Sto usando HTMLParser per analizzare le pagine I pull down con urllib e sto incontrando le eccezioni UnicodeDecodeError quando si passa ad alcune persone su HTMLParser.Python HTMLParser: UnicodeDecodeError

Ho provato ad utilizzare chardet per rilevare le codifiche e convertire in ascii, oppure utf-8 (il docs non sembrano dire quello che dovrebbe essere). la perdita di dati è accettabile, ma mentre le linee di decodifica/codifica funzionano bene, ottengo sempre l'errore dopo self.feed().

Le informazioni sono lì se ho appena print fuori.

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 

ecco l'output:

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) 

risposta

17

È UTF-8, infatti. Questo funziona:

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 

Non è necessario chardet, Youtube non sono idioti, in realtà inviare la codifica corretta nell'intestazione.

1

Che codifica fa chardet dire che è?

Spiegare "Le informazioni sono lì se lo stampo": cos'è "it"? Se puoi leggerlo e ha senso quando lo stampi sulla tua console, allora deve essere nella solita/predefinita codifica per il tuo sistema; Cos'è quello? Quale sistema operativo? Quale locale?

Puoi fornirci un URL tipico per effettuare una query in modo che possiamo ispezionare da soli ciò che stai vedendo?

In un punto del codice, decodificare l'output, quindi distruggerlo immediatamente utilizzando .encode('ascii', 'ignore'); perché?

+0

il codice che ho pubblicato include un URL di esempio. chardet dice che l'url di esempio è utf-8, ma quando si usa il programma, si incontrano altre codifiche (tutte danno lo stesso errore unicode). Posso leggerlo e ha senso quando stampa sulla mia console. Ubuntu 10.10 è il mio sistema operativo. Non ho alcun ragionamento per la decodifica/codifica. Sto faticando a capirlo, e ho trovato numerosi suggerimenti contrastanti attraverso google, che è uno di loro testualmente (non ricordo da dove). grazie per il vostro aiuto. Post scriptum 'Page.decode ('utf-8'); self.feed (pagina) 'dà lo stesso errore. –

+0

Giusto per chiarire, hai provato 'page = page.decode ('utf-8'); self.feed (Pagina) '? – William

+0

sì, mi ha dato lo stesso errore: 'UnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xc3 nella posizione 16688: ordinale non nel range (128)' –

Problemi correlati