UnicodeEncodeError: кодек 'charmap' не может кодировать символы

206

Я пытаюсь почистить сайт, но он выдает ошибку.

Я использую следующий код:

import urllib.request
from bs4 import BeautifulSoup

get = urllib.request.urlopen("https://www.website.com/")
html = get.read()

soup = BeautifulSoup(html)

print(soup)

И я получаю следующую ошибку:

File "C:\Python34\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 70924-70950: character maps to <undefined>

Что я могу сделать, чтобы это исправить?

SstrykerR
источник

Ответы:

258

Я получал то же самое UnicodeEncodeErrorпри сохранении очищенного веб-содержимого в файл. Чтобы исправить это, я заменил этот код:

with open(fname, "w") as f:
    f.write(html)

с этим:

import io
with io.open(fname, "w", encoding="utf-8") as f:
    f.write(html)

Использование ioобеспечивает обратную совместимость с Python 2.

Если вам нужна только поддержка Python 3, вы можете использовать встроенную openфункцию:

with open(fname, "w", encoding="utf-8") as f:
    f.write(html)
twasbrillig
источник
6
В Mac (Python 3) прекрасно работает с просто открытым без кодирования, но в Windows (W10, Python3) это не вариант. Просто работает таким образом, с параметром encoding = "utf-8".
xtornasol512
3
Спасибо. Это сработало для меня, я работал с XML-файлами и записывал результат xml.toprettyxml () в новый файл
Луис Кабрера Бенито
1
Это должен быть принятый ответ, потому что он в конечном итоге записывает строку в вывод, а не строковое представление байтов.
Shirkan
ОП попросил прочитать файл, но не записать файл. Проблема, похоже, связана с консолью.
NaturalBornCamper
Это работает. Но вам не нужно было использовать io, все, что вам нужно было сделать, это включить encoding="utf-8"функцию open
Mafia
188

Я исправил это, добавив .encode("utf-8")кsoup .

Это означает, что print(soup)становится print(soup.encode("utf-8")).

SstrykerR
источник
3
не жестко кодируйте кодировку символов вашей среды (например, консоли) внутри вашего скрипта, вместо этого печатайте Unicode напрямую
jfs
Это просто распечатка repr bytesобъекта, который будет печататься как беспорядок \xпоследовательностей, если есть много текста в кодировке UTF-8. Я рекомендую использовать win_unicode_console, как предлагает @JFSebastian.
Eryk Sun
2
Я использовал вышеупомянутое решение, но все равно получаю проблемы: класс MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8"))) UnicodeEncodeError: 'charmap' codec can ' t кодирует символ '\ u2019' в позиции 87: символ отображается на <undefined>
Vivek
2
Это заставляет его печатать b'\x02x\xc2\xa9'(объект байтов) вместо этого
MilkyWay90
1
print(soup.encode("utf-8"))работал для меня, но до этого я должен был также добавитьwith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
TheWalkingData
44

В Python 3.7 и под управлением Windows 10 это работало (я не уверен, будет ли оно работать на других платформах и / или в других версиях Python)

Замена этой строки:

with open('filename', 'w') as f:

С этим:

with open('filename', 'w', encoding='utf-8') as f:

Причина, по которой он работает, заключается в том, что при использовании файла кодировка изменяется на UTF-8, поэтому символы в UTF-8 могут быть преобразованы в текст, вместо того, чтобы возвращать ошибку при обнаружении символа UTF-8, который является не поддерживается текущей кодировкой.

Саббир Ахмед
источник
1
print (суп) return \ xd0 \ xbf \ xd0 \ xbe \ xd0 \ xb6 \ xd0 \ xb0 \ xd0 \ xbb \ xd1 \ x83 \ xd0 \ xb9 \ xd
Кофе inTime
12

При сохранении ответа на запрос get та же ошибка была выдана на Python 3.7 в окне 10. Ответ, полученный от URL, кодировка была UTF-8, поэтому всегда рекомендуется проверять кодировку, чтобы ее можно было пропустить, чтобы избежать такой тривиальной проблемы. как это действительно убивает много времени в производстве

import requests
resp = requests.get('https://en.wikipedia.org/wiki/NIFTY_50')
print(resp.encoding)
with open ('NiftyList.txt', 'w') as f:
    f.write(resp.text)

Когда я добавил encoding = "utf-8" с помощью команды open, он сохранил файл с правильным ответом

with open ('NiftyList.txt', 'w', encoding="utf-8") as f:
    f.write(resp.text)
Абхишек Джайн
источник
10

Даже я столкнулся с той же проблемой с кодировкой, которая возникает, когда вы пытаетесь распечатать, прочитать / написать или открыть ее. Как уже упоминалось выше, добавление .encoding = "utf-8" поможет, если вы пытаетесь его распечатать.

soup.encode ( "UTF-8")

Если вы пытаетесь открыть очищенные данные и, возможно, записать их в файл, откройте файл с помощью (......, encoding = "utf-8")

с открытым (filename_csv, 'w', newline = '', encoding = "utf-8") как csv_file:

Пардху Гопалам
источник
6

Для тех, кто все еще получает эту ошибку, добавление encode("utf-8")к soupтакже исправит это.

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)
Псевдо-судо
источник
2
soupбольше не является BeautifulSoupобъектом после того, как вы это сделаете, поэтому им нельзя манипулировать или искать
NaturalBornCamper