UnicodeEncodeError: кодек "charmap" не може кодувати символи


205

Я намагаюся скребти веб-сайт, але це дає мені помилку.

Я використовую такий код:

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>

Що я можу зробити, щоб це виправити?

Відповіді:


257

Я отримував те саме, 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
Це має бути прийнятою відповіддю, оскільки вона врешті запише рядок до виводу, а не рядкове представлення байтів.
Ширкан

ОП просило прочитати файл, проте не записувати файл. Здається, це питання пов'язане з консолями.
NaturalBornCamper

187

Я виправив це, додавши .encode("utf-8")в soup.

Це означає, що print(soup)стає print(soup.encode("utf-8")).


3
не жорстко кодуйте кодування символів вашого середовища (наприклад, консолі) всередині вашого сценарію, друкуйте Unicode безпосередньо замість цього
jfs

Це лише друк репр- bytesоб'єкта, який буде надрукований як безлад \xпослідовностей, якщо є багато тексту, закодованої UTF-8. Я рекомендую використовувати win_unicode_console, як пропонує @JFSebastian
Ерік Нд

2
Я використовував вищезазначене рішення, але під час отримання підвіконь виникають проблеми: клас MyStreamListener (tweepy.StreamListener): def on_status (самостійна, статус): print (str (status.encode ("utf-8"))) UnicodeEncodeError: 'charmap' кодек може ' t кодуйте символ '\ u2019' у позиції 87: символьні карти на <визначено>
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
друк (суп) повернення \ xd0 \ xbf \ xd0 \ xbe \ xd0 \ xb6 \ xd0 \ xb0 \ xd0 \ xbb \ xd1 \ x83 \ xd0 \ xb9 \ xd
Кава в час

12

Під час збереження відповіді на запит на отримання, та сама помилка була закинута на 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" допоможе, якщо ви намагаєтеся роздрукувати його.

суп.код ("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
soupBeautifulSoupпісля цього ви більше не є об'єктом, щоб ним не можна було маніпулювати чи шукати
NaturalBornCamper
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.