2011-04-21 13 views
6

estoy usando BeautifulSoup para extraer las noticias (sólo los títulos) de Hacker News y tener esta cantidad hasta el ahora-findall BeautifulSoup con el error de clase atributo, Unicode de codificación

import urllib2 
from BeautifulSoup import BeautifulSoup 

HN_url = "http://news.ycombinator.com" 

def get_page(): 
    page_html = urllib2.urlopen(HN_url) 
    return page_html 

def get_stories(content): 
    soup = BeautifulSoup(content) 
    titles_html =[] 

    for td in soup.findAll("td", { "class":"title" }): 
     titles_html += td.findAll("a") 

    return titles_html 

print get_stories(get_page() 

)

Cuando corro el código, sin embargo, da un error-

Traceback (most recent call last): 
    File "terminalHN.py", line 19, in <module> 
    print get_stories(get_page()) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe2' in position 131: ordinal not in range(128) 

¿Cómo hago para que funcione?

Respuesta

6

Porque BeautifulSoup funciona internamente con cadenas de caracteres unicode. La impresión de cadenas unicode en la consola hará que Python intente la conversión de unicode a la codificación predeterminada de Python, que generalmente es ascii. En general, esto no funcionará para sitios web que no sean de ASCII. Puede aprender los conceptos básicos sobre Python y Unicode buscando en Google "python + unicode". Mientras tanto convertir sus cadenas Unicode UTF-8 usando

print some_unicode_string.decode('utf-8') 
+3

Quiere '.encode ('utf-8')' convertir de una cadena Unicode a una cadena codificada en UTF-8. – Alex

0

Funciona bien, lo que está roto es la salida. Codifique explícitamente el conjunto de caracteres de su consola o busque una forma diferente de ejecutar el código (por ejemplo, desde IDLE).

1

Una cosa a tener en cuenta sobre el código es que findAll devuelve una lista (en este caso una lista de objetos BeautifulSoup) y sólo quieren que los títulos. Es posible que desee utilizar find en su lugar. Y en lugar de imprimir una lista de objetos BeautifulSoup, dices que solo quieres los títulos. Las siguientes obras excelentes, por ejemplo:

import urllib2 
from BeautifulSoup import BeautifulSoup 

HN_url = "http://news.ycombinator.com" 

def get_page(): 
    page_html = urllib2.urlopen(HN_url) 
    return page_html 

def get_stories(content): 
    soup = BeautifulSoup(content) 
    titles = [] 

    for td in soup.findAll("td", { "class":"title" }): 
     a_element = td.find("a") 
     if a_element: 
      titles.append(a_element.string) 

    return titles 

print get_stories(get_page()) 

Así que ahora get_stories() devuelve una lista de objetos unicode, que imprime como era de esperar.

Cuestiones relacionadas