UnicodeEncodeError: el códec 'charmap' no puede codificar caracteres

206

Estoy tratando de raspar un sitio web, pero me da un error.

Estoy usando el siguiente código:

import urllib.request
from bs4 import BeautifulSoup

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

soup = BeautifulSoup(html)

print(soup)

Y obtengo el siguiente error:

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>

¿Qué puedo hacer para arreglar esto?

SstrykerR
fuente

Respuestas:

258

Estaba obteniendo lo mismo UnicodeEncodeErroral guardar contenido web raspado en un archivo. Para solucionarlo, reemplacé este código:

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

con este:

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

El uso iole brinda compatibilidad con Python 2.

Si solo necesita admitir Python 3, puede usar la openfunción integrada en su lugar:

with open(fname, "w", encoding="utf-8") as f:
    f.write(html)
twasbrillig
fuente
66
En mac (python 3) funciona perfectamente con solo abrir sin codificación, pero en windows (w10, python3) no es una opción. Simplemente funciona de esa manera, con encoding = "utf-8" param.
xtornasol512
3
Gracias. A mí me funcionó, estaba trabajando con archivos xml y escribiendo el resultado de xml.toprettyxml () en un nuevo archivo
Luis Cabrera Benito
1
Esta debería ser la respuesta aceptada porque eventualmente escribirá una cadena en la salida, y no una representación en cadena de bytes.
Shirkan
OP solicitó leer el archivo sin embargo, no escribir el archivo. El problema parece estar relacionado con la consola.
NaturalBornCamper
188

Lo arreglé agregando .encode("utf-8")a soup.

Eso significa que se print(soup)convierte print(soup.encode("utf-8")).

SstrykerR
fuente
3
no codifique la codificación de caracteres de su entorno (p. ej., consola) dentro de su script, imprima Unicode directamente en su lugar
jfs
Esto es solo imprimir la reproducción de un bytesobjeto, que se imprimirá como un desorden de \xsecuencias si hay mucho texto codificado en UTF-8. Recomiendo usar win_unicode_console, como sugiere @JFSebastian.
Eryk dom
2
Utilicé la solución anterior pero aún tengo problemas: clase MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8"))) UnicodeEncodeError: 'charmap' codec can ' t codifica el carácter '\ u2019' en la posición 87: el carácter se asigna a <indefinido>
Vivek
2
Esto hace que se imprima b'\x02x\xc2\xa9'(un objeto de bytes) en su lugar
MilkyWay90
1
print(soup.encode("utf-8"))funcionó para mí, pero antes de eso también tuve que agregarwith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
TheWalkingData
44

En Python 3.7, y ejecutar Windows 10 esto funcionó (no estoy seguro de si funcionará en otras plataformas y / u otras versiones de Python)

Reemplazando esta línea:

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

Con este:

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

La razón por la que funciona es porque la codificación se cambia a UTF-8 cuando se usa el archivo, por lo que los caracteres en UTF-8 pueden convertirse en texto, en lugar de devolver un error cuando encuentra un carácter UTF-8 que es no suppord por la codificación actual.

Sabbir Ahmed
fuente
1
print (sopa) return \ xd0 \ xbf \ xd0 \ xbe \ xd0 \ xb6 \ xd0 \ xb0 \ xd0 \ xbb \ xd1 \ x83 \ xd0 \ xb9 \ xd
Café en tiempo
12

Al guardar la respuesta de la solicitud get, se arrojó el mismo error en Python 3.7 en la ventana 10. La respuesta recibida de la URL, la codificación fue UTF-8, por lo que siempre se recomienda verificar la codificación para que se pueda pasar para evitar un problema tan trivial ya que realmente mata mucho tiempo en producción

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)

Cuando agregué encoding = "utf-8" con el comando abierto, guardé el archivo con la respuesta correcta

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

Incluso me enfrenté al mismo problema con la codificación que ocurre cuando intentas imprimirlo, leerlo / escribirlo o abrirlo. Como otros mencionaron anteriormente, agregar .encoding = "utf-8" ayudará si está intentando imprimirlo.

soup.encode ("utf-8")

Si está intentando abrir datos raspados y tal vez escribirlos en un archivo, abra el archivo con (......, encoding = "utf-8")

con abierto (filename_csv, 'w', newline = '', encoding = "utf-8") como csv_file:

Pardhu Gopalam
fuente
6

Para aquellos que todavía reciben este error, agregar encode("utf-8")a souptambién solucionará esto.

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)
Pseudo Sudo
fuente
2
soupya no es un BeautifulSoupobjeto después de hacer esto, por lo que no se puede manipular ni buscar
NaturalBornCamper