BeautifulSoup находит все с атрибутом класса - ошибка кодирования юникода

Я использую BeautifulSoup для извлечения новостей (только заголовки) из Hacker News, и до сих пор у меня есть это:

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()

)

Однако, когда я запускаю код, он выдает ошибку -

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)

Как заставить это работать?


person Community    schedule 21.04.2011    source источник


Ответы (3)


Потому что BeautifulSoup внутренне работает со строками юникода. Печать строк юникода на консоли заставит Python попытаться преобразовать юникод в кодировку Python по умолчанию, которая обычно представляет собой ascii. Обычно это не работает для веб-сайта, отличного от ascii. Вы можете изучить основы Python и Unicode, погуглив «python + unicode». Тем временем преобразуйте строки Unicode в utf-8, используя

print some_unicode_string.decode('utf-8')
person Andreas Jung    schedule 21.04.2011
comment
Вы хотите, чтобы .encode('utf-8') преобразовывал строку Unicode в строку в кодировке UTF-8. - person Alex; 21.04.2011

Следует отметить, что в вашем коде findAll возвращает список (в данном случае список объектов BeautifulSoup), и вам нужны только заголовки. Вместо этого вы можете использовать find. И вместо того, чтобы распечатать список объектов BeautifulSoup, вы говорите, что вам нужны только заголовки. Например, следующее работает нормально:

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())

Так что теперь get_stories() возвращает список unicode объектов, который распечатывается так, как вы и ожидали.

person Mark Longair    schedule 21.04.2011

Он работает нормально, что сломано, так это выход. Либо явно закодируйте кодировку вашей консоли, либо найдите другой способ запуска вашего кода (например, из IDLE).

person Ignacio Vazquez-Abrams    schedule 21.04.2011