Кодек Python 'latin-1' не может кодировать символы - Как игнорировать символы? - PullRequest
0 голосов
/ 15 февраля 2019

Вот суть моего кода.Он пытается получить текст со старого сайта.Это не мое, поэтому я не могу изменить источник.

from bs4 import BeautifulSoup
import requests

response = requests.get("https://mattgemmell.com/network-link-conditioner-in-lion/")
data = response.text
soup = BeautifulSoup(data, 'lxml')
article = soup.find_all('article')[0]
text = article.find_all('p')[1].text 
print(text)

Дает это:

'Если вы \ x80 \ x99re разработчик приложений для Mac или iOS, которые используют сети,В инструментах разработчика для Mac OS X 10.7 появилась новая функция \ x80 \ x99s \ x80 \ x9cLionâ \ x80 \ x9d (прочитайте мой обзор в The Guardian), которая будет вам полезна.Эта краткая статья описывает, как это работает. '

Я могу использовать это для преобразования таких частей, как â \ x80 \ x99:

converted_text = bytes(text, 'latin-1').decode('utf-8')

На самом деле работает.

Но если выполучить другую часть текста:

text = article.find_all('p')[8].text 

Дает мне:

'\ n ← Найти шаблоны в тексте на Lion \ nИспользовать пробелы в OS X Lion → \ n'

И использование bytes(text, 'latin-1') дает мне:

кодек 'latin-1' не может кодировать символ '\ u2190' в позиции 1: порядковый номер не в диапазоне (256)

IПредположим, это стрелки?Как я могу сделать так, чтобы все нелатинские символы автоматически игнорировались и отбрасывались.

Любые идеи будут наиболее полезны!

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Вы не хотите игнорировать этих персонажей.Они являются признаком того, что полученные вами данные были декодированы с использованием неправильной кодировки символов.В вашем случае requests неправильно догадался, что кодировка latin-1.Реальная кодировка - utf-8 и указывается в теге <meta> в ответе HTML.requests - библиотека для работы с HTTP, она не знает о HTML.Поскольку заголовок Content-Type не указывает кодировку, requests прибегает к угадыванию кодировки.BeautifulSoup, однако, это библиотека для работы с HTML, и она очень хороша для обнаружения кодировок.Таким образом, вы хотите получить необработанные байты из ответа и передать его BeautifulSoup.т. е.

from bs4 import BeautifulSoup
import requests

response = requests.get("https://mattgemmell.com/network-link-conditioner-in-lion/")
data = response.content # we now get `content` rather than `text`
assert type(data) is bytes
soup = BeautifulSoup(data, 'lxml')
article = soup.find_all('article')[0]
text = article.find_all('p')[1].text 
print(text)

assert type(text) is str
assert 'Mac OS X 10.7 “Lion”' in text
0 голосов
/ 15 февраля 2019

Используйте третий аргумент для bytes, чтобы сообщить ему, как обрабатывать ошибки:

converted_text = bytes(text, 'latin-1', 'ignore')
                                         ^^^^^^

Вы потеряете стрелки, но в остальном все в порядке:

>>> text = '\n← Find Patterns in text on Lion\nUsing Spaces on OS X Lion →\n'
>>> converted_text = bytes(text, 'latin-1', 'ignore')
>>> converted_text
'\n Find Patterns in text on Lion\nUsing Spaces on OS X Lion \n'

Вот ещеинформация об аргументе из документации - https://docs.python.org/3.3/howto/unicode.html:

Аргумент ошибки указывает ответ, когда входная строка не может быть преобразована в соответствии с правилами кодировки.Допустимыми значениями для этого аргумента являются «строгий» (вызов исключения UnicodeDecodeError), «замена» (используйте U + FFFD, REPLACEMENT CHARACTER) или «игнорирование» (просто оставьте символ вне результата Unicode).

...