UnicodeEncodeError: le codec 'charmap' ne peut pas coder les caractères


206

J'essaie de gratter un site Web, mais cela me donne une erreur.

J'utilise le code suivant:

import urllib.request
from bs4 import BeautifulSoup

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

soup = BeautifulSoup(html)

print(soup)

Et j'obtiens l'erreur suivante:

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>

Que puis-je faire pour résoudre ce problème?

Réponses:


258

J'obtenais la même chose UnicodeEncodeErrorlors de l'enregistrement du contenu Web gratté dans un fichier. Pour le réparer, j'ai remplacé ce code:

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

avec ça:

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

L'utilisation iovous donne une compatibilité descendante avec Python 2.

Si vous avez seulement besoin de prendre en charge Python 3, vous pouvez utiliser la openfonction intégrée à la place:

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

6
Dans mac (python 3) fonctionne parfaitement avec juste ouvert sans encodage, mais dans windows (w10, python3) n'est pas une option. Fonctionne juste de cette manière, avec encoding = "utf-8" param.
xtornasol512

3
Je vous remercie. Cela a fonctionné pour moi, je travaillais avec des fichiers xml et j'écrivais le résultat de xml.toprettyxml () dans un nouveau fichier
Luis Cabrera Benito

1
Cela devrait être la réponse acceptée car elle finira par écrire une chaîne dans la sortie, et non une représentation sous forme de chaîne d'octets.
Shirkan

OP a cependant demandé de lire le fichier, pas d'écrire le fichier. Le problème semble être lié à la console.
NaturalBornCamper

188

Je l'ai corrigé en ajoutant .encode("utf-8")à soup.

Cela signifie que cela print(soup)devient print(soup.encode("utf-8")).


3
ne codez pas en dur le codage des caractères de votre environnement (par exemple, la console) dans votre script, imprimez directement Unicode à la place
jfs

Il s'agit simplement d'imprimer la représentation d'un bytesobjet, qui s'imprimera comme un désordre de \xséquences s'il y a beaucoup de texte encodé en UTF-8. Je recommande d'utiliser win_unicode_console, comme le suggère @JFSebastian.
Eryk Sun

2
J'ai utilisé la solution ci-dessus mais j'obtiens toujours des problèmes: classe MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8"))) UnicodeEncodeError: le codec 'charmap' peut '' t encoder le caractère '\ u2019' en position 87: mappage de caractères à <non défini>
Vivek

2
Cela le fait imprimer à la place b'\x02x\xc2\xa9'(un objet en octets)
MilkyWay90

1
print(soup.encode("utf-8"))travaillé pour moi, mais avant cela, je devais également ajouterwith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
TheWalkingData

44

En Python 3.7 et fonctionnant sous Windows 10, cela a fonctionné (je ne sais pas si cela fonctionnera sur d'autres plates-formes et / ou d'autres versions de Python)

Remplacement de cette ligne:

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

Avec ça:

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

La raison pour laquelle cela fonctionne est que le codage est modifié en UTF-8 lors de l'utilisation du fichier, de sorte que les caractères dans UTF-8 peuvent être convertis en texte, au lieu de renvoyer une erreur lorsqu'il rencontre un caractère UTF-8 qui est pas supporté par l'encodage actuel.


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

12

Lors de l'enregistrement de la réponse de la demande get, la même erreur a été émise sur Python 3.7 sur la fenêtre 10. La réponse reçue de l'URL, le codage était UTF-8, il est donc toujours recommandé de vérifier le codage afin qu'il puisse être transmis pour éviter un problème aussi trivial car il tue vraiment beaucoup de temps en production

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)

Lorsque j'ai ajouté encoding = "utf-8" avec la commande open, il a enregistré le fichier avec la bonne réponse

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

10

Même moi, j'ai rencontré le même problème avec l'encodage qui se produit lorsque vous essayez de l'imprimer, de le lire / écrire ou de l'ouvrir. Comme d'autres l'ont mentionné ci-dessus, l'ajout de .encoding = "utf-8" vous aidera si vous essayez de l'imprimer.

soup.encode ("utf-8")

Si vous essayez d'ouvrir des données grattées et peut-être de les écrire dans un fichier, ouvrez le fichier avec (......, encoding = "utf-8")

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


6

Pour ceux qui obtiennent toujours cette erreur, l'ajout encode("utf-8")à soupcorrigera également le problème.

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

2
soupn'est plus un BeautifulSoupobjet après cela, il ne peut donc pas être manipulé ou recherché
NaturalBornCamper
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.