UnicodeEncodeError: il codec 'charmap' non può codificare i caratteri


206

Sto cercando di raschiare un sito Web, ma mi dà un errore.

Sto usando il seguente codice:

import urllib.request
from bs4 import BeautifulSoup

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

soup = BeautifulSoup(html)

print(soup)

E sto ottenendo il seguente errore:

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>

Cosa posso fare per risolvere questo problema?

Risposte:


258

Stavo ottenendo lo stesso UnicodeEncodeErrorquando salvavo il contenuto Web raschiato su un file. Per risolverlo ho sostituito questo codice:

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

con questo:

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

L'uso ioti offre la retrocompatibilità con Python 2.

Se devi solo supportare Python 3 puoi invece utilizzare la openfunzione integrata:

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

6
In mac (python 3) funziona perfettamente con appena aperto senza codifica, ma in windows (w10, python3) non è un'opzione. Funziona solo in quel modo, con encoding = "utf-8" param.
xtornasol512

3
Grazie. Ha funzionato per me, stavo lavorando con file xml e scrivendo il risultato di xml.toprettyxml () in un nuovo file
Luis Cabrera Benito

1
Questa dovrebbe essere la risposta accettata perché alla fine scriverà una stringa nell'output e non una rappresentazione in stringa di byte.
Shirkan,

OP ha richiesto tuttavia di leggere il file, non di scrivere il file. Il problema sembra essere relativo alla console.
NaturalBornCamper

188

L'ho risolto aggiungendo .encode("utf-8")a soup.

Ciò significa che print(soup)diventa print(soup.encode("utf-8")).


3
non codificare la codifica dei caratteri del tuo ambiente (es. console) all'interno dello script, stampa invece direttamente Unicode
jfs

Questo è solo la stampa del repr di un bytesoggetto, che verrà stampato come un pasticcio di \xsequenze se c'è molto testo codificato UTF-8. Consiglio di usare win_unicode_console, come suggerisce @JFSebastian.
Eryk Sun,

2
Ho usato la soluzione di cui sopra ma ho sempre riscontrato problemi: class MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8"))) UnicodeEncodeError: 'charmap' codec can ' t codifica il carattere '\ u2019' in posizione 87: il carattere viene mappato su <undefined>
Vivek,

2
Questo lo fa stampare b'\x02x\xc2\xa9'(un oggetto byte) invece
MilkyWay90

1
print(soup.encode("utf-8"))ha funzionato per me, ma prima dovevo anche aggiungerewith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
TheWalkingData

44

In Python 3.7 e con Windows 10 funzionava (non sono sicuro che funzionerà su altre piattaforme e / o altre versioni di Python)

Sostituzione di questa riga:

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

Con questo:

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

Il motivo per cui funziona è perché la codifica viene modificata in UTF-8 quando si utilizza il file, quindi i caratteri in UTF-8 possono essere convertiti in testo, invece di restituire un errore quando incontra un carattere UTF-8 che è non supporta la codifica corrente.


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

12

Durante il salvataggio della risposta di get request, lo stesso errore è stato generato su Python 3.7 nella finestra 10. La risposta ricevuta dall'URL, la codifica era UTF-8, quindi si consiglia sempre di controllare la codifica in modo che possa essere passato lo stesso per evitare problemi così banali in quanto uccide davvero molto tempo in produzione

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)

Quando ho aggiunto encoding = "utf-8" con il comando open ha salvato il file con la risposta corretta

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

10

Anche io ho riscontrato lo stesso problema con la codifica che si verifica quando si tenta di stamparlo, leggerlo / scriverlo o aprirlo. Come altri menzionati sopra, l'aggiunta di .encoding = "utf-8" ti aiuterà se stai provando a stamparlo.

soup.encode ( "utf-8")

Se si sta tentando di aprire dati di cui è stato eseguito il scraping e magari di scriverli in un file, aprire il file con (......, encoding = "utf-8")

con open (nome_file_cv, 'w', newline = '', encoding = "utf-8") come csv_file:


6

Per coloro che continuano a ricevere questo errore, l'aggiunta encode("utf-8")a souprisolverà anche questo.

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

2
soupnon è più un BeautifulSoupoggetto dopo averlo fatto, quindi non può essere manipolato o cercato
NaturalBornCamper
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.