UnicodeEncodeError: codec 'charmap' tidak dapat menyandikan karakter


206

Saya mencoba mengikis situs web, tetapi itu memberi saya kesalahan.

Saya menggunakan kode berikut:

import urllib.request
from bs4 import BeautifulSoup

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

soup = BeautifulSoup(html)

print(soup)

Dan saya mendapatkan kesalahan berikut:

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>

Apa yang bisa saya lakukan untuk memperbaikinya?

Jawaban:


258

Saya mendapatkan hal yang sama UnicodeEncodeErrorketika menyimpan konten web tergores ke file. Untuk memperbaikinya saya mengganti kode ini:

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

dengan ini:

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

Menggunakan iomemberi Anda kompatibilitas dengan Python 2.

Jika Anda hanya perlu mendukung Python 3, Anda dapat menggunakan openfungsi builtin sebagai gantinya:

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

6
Di mac (python 3) berfungsi sempurna dengan hanya membuka tanpa pengkodean, tetapi di windows (w10, python3) bukan pilihan. Hanya berfungsi seperti itu, dengan encoding = "utf-8" param.
— xtornasol512

3
Terima kasih. Ini bekerja untuk saya, saya bekerja dengan file xml dan menulis hasil xml.toprettyxml () dalam file baru
— Luis Cabrera Benito

1
Ini harus menjadi jawaban yang diterima karena pada akhirnya akan menulis string ke output, dan bukan representasi string byte.
— Shirkan

Namun OP meminta untuk membaca file, bukan menulis file. Masalah ini tampaknya terkait dengan konsol.
— NaturalBornCamper

188

Aku tetap dengan menambahkan .encode("utf-8")ke soup.

Itu artinya print(soup)menjadi print(soup.encode("utf-8")).


3
jangan hardcode pengkodean karakter lingkungan Anda (misalnya, konsol) di dalam skrip Anda, cetak Unicode langsung sebagai gantinya
— jfs

Ini hanya mencetak repr dari suatu bytesobjek, yang akan mencetak sebagai kekacauan \xurutan jika ada banyak teks yang dikodekan UTF-8. Saya sarankan menggunakan win_unicode_console, seperti yang disarankan @JFSebastian.
— Eryk Sun

2
Saya menggunakan solusi di atas tetapi masih mendapatkan masalah: kelas MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8"))) UnicodeEncodeError: 'charmap' codec can ' t menyandikan karakter '\ u2019' di posisi 87: peta karakter ke <undefined>
— Vivek

2
Ini membuatnya mencetak b'\x02x\xc2\xa9'(objek byte) sebagai gantinya
— MilkyWay90

1
print(soup.encode("utf-8"))bekerja untuk saya, tetapi sebelum itu saya juga harus menambahkanwith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
— TheWalkingData

44

Dalam Python 3.7, dan menjalankan Windows 10 ini berhasil (saya tidak yakin apakah itu akan bekerja pada platform lain dan / atau versi Python lainnya)

Mengganti baris ini:

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

Dengan ini:

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

Alasan mengapa itu bekerja adalah karena pengkodean diubah menjadi UTF-8 saat menggunakan file, sehingga karakter dalam UTF-8 dapat dikonversi ke teks, bukannya mengembalikan kesalahan ketika bertemu dengan karakter UTF-8 yang tidak didukung oleh pengkodean saat ini.


1
print (soup) return \ xd0 \ xbf \ xd0 \ xbe \ xd0 \ xb6 \ xd0 \ xb0 \ xd0 \ xbb \ xd1 \ x83 \ xd0 \ xb9 \ xd
— Kopi

12

Saat menyimpan respons permintaan dapatkan, kesalahan yang sama dilemparkan ke Python 3.7 pada jendela 10. Respons yang diterima dari URL, penyandian adalah UTF-8 sehingga selalu disarankan untuk memeriksa penyandian agar hal yang sama dapat dilewatkan untuk menghindari masalah sepele seperti itu. karena benar-benar membunuh banyak waktu dalam produksi

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)

Ketika saya menambahkan encoding = "utf-8" dengan perintah terbuka itu menyimpan file dengan respons yang benar

with open ('NiftyList.txt', 'w', encoding="utf-8") as f:
    f.write(resp.text)

10

Bahkan saya menghadapi masalah yang sama dengan pengkodean yang terjadi ketika Anda mencoba mencetaknya, membaca / menulis atau membukanya. Seperti yang disebutkan di atas, menambahkan .encoding = "utf-8" akan membantu jika Anda ingin mencetaknya.

soup.encode ("utf-8")

Jika Anda mencoba membuka data yang tergores dan mungkin menulisnya ke dalam file, kemudian buka file dengan (......, encoding = "utf-8")

dengan open (filename_csv, 'w', newline = '', encoding = "utf-8") sebagai csv_file:


6

Bagi mereka masih mendapatkan kesalahan ini, menambahkan encode("utf-8")untuk soupjuga akan memperbaiki hal ini.

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)

2
soupbukan lagi BeautifulSoupobjek setelah Anda melakukan ini sehingga tidak dapat dimanipulasi atau dicari
— NaturalBornCamper
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.