Ошибки Unicode при печати python красивых суповых объектов - PullRequest
0 голосов
/ 28 апреля 2020
import bs4 as bs
import urllib.request

sauce = urllib.request.urlopen('https://stats.swehockey.se/Teams/Info/TeamRoster/10333').read()
soup = bs.BeautifulSoup(sauce, 'lxml')

print(soup)

Этот код выдает следующую ошибку

UnicodeEncodeError: 'ascii' codec can't encode character '\xbb' in position 1509: ordinal not in range(128)

Я пробовал несколько обходных путей, но все они имеют некоторые недостатки. После поиска в stackoverflow я нашел решение изменить .stdout, например:

import bs4 as bs
import urllib.request
import sys
import codecs
sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
sys.stderr = codecs.getwriter('utf-8')(sys.stderr)

sauce = urllib.request.urlopen('https://stats.swehockey.se/Teams/Info/TeamRoster/10333').read()
soup = bs.BeautifulSoup(sauce, 'lxml')

print(soup)

Я больше не получаю сообщение об ошибке, однако вывод больше не направлен на терминал. Я не уверен, почему это происходит. Использование метода .prettify('utf-8') также избавляет от ошибки и выдает выходные данные, однако результирующий объект является строкой, а не красивым суповым объектом и, следовательно, не имеет ни одного из связанных методов bs (например, .find_all ()). Аналогичная проблема возникает с подходом .encode('utf-8').

Кроме того, я заметил, что в выводе есть много символов \ r и \ n, все еще в прекрасном суповом объекте вместо чистого html содержимого.

Я хочу красивый суповый объект без каких-либо символов \ r или \ n, которые я могу напечатать на терминал.

1 Ответ

0 голосов
/ 07 мая 2020

В вашем коде:

sauce = urllib.request.urlopen('https://stats.swehockey.se/Teams/Info/TeamRoster/10333').read()
soup = bs.BeautifulSoup(sauce, 'lxml')

sauce имеет тип bytes. Когда вы передаете это в bs.BeautifulSoup(), BeautifulSoup пытается декодировать эти байты как строку ascii и терпит неудачу, потому что на самом деле это строка utf-8 - согласно обоим заголовкам ответа Content-Type (text/html; charset=utf-8) а также тег meta в начале документа html (<meta charset="utf-8" />).

Первый аргумент для bs.BeautifulSoup(), markup, принимает строку или файл- как объект, представляющий разметку для анализа . Вы должны явно декодировать эти байты как utf-8 закодированную строку и использовать ее вместо необработанных байтов, например так:

sauce = urllib.request.urlopen('https://stats.swehockey.se/Teams/Info/TeamRoster/10333').read().decode('utf-8')
soup = bs.BeautifulSoup(sauce, 'lxml')

Кроме того, я заметил, что в выводе есть много красивых символов \ r и \ n все еще находятся в красивом объекте супа вместо чистого содержимого html.

Я хочу красивый объект супа без каких-либо символов \ r или \ n, которые можно распечатать терминал.

Символы \r и \n являются просто представлениями символа новой строки. Если вы напечатаете их или просмотрите их в текстовом редакторе, они будут отображаться как настоящие новые строки.

...