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>

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

Ответы:


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)

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")).


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.