UnicodeEncodeError: o codec 'charmap' não pode codificar caracteres

205

Estou tentando raspar um site, mas isso gera um erro.

Estou usando o seguinte 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)

E estou recebendo o seguinte erro:

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>

Oque posso fazer para consertar isso?

SstrykerR
fonte

Respostas:

258

Eu estava recebendo o mesmo UnicodeEncodeErrorao salvar o conteúdo da Web raspado em um arquivo. Para corrigi-lo, substituí este código:

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

com isso:

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

Usar iofornece compatibilidade retroativa com o Python 2.

Se você precisar apenas suportar o Python 3, poderá usar a openfunção embutida:

with open(fname, "w", encoding="utf-8") as f:
    f.write(html)
twasbrillig
fonte
6
No mac (python 3) funciona perfeitamente com apenas abrir sem codificação, mas no windows (w10, python3) não é uma opção. Apenas funciona dessa maneira, com o parâmetro encoding = "utf-8".
precisa saber é o seguinte
3
Obrigado. Ela trabalhou para mim, eu estava trabalhando com arquivos XML e escrever o resultado de xml.toprettyxml () em um novo arquivo
Luis Cabrera Benito
1
Essa deve ser a resposta aceita, pois acabará gravando uma string na saída, e não uma representação de bytes.
Shirkan 14/02/19
O OP solicitou a leitura do arquivo, no entanto, não o gravou. O problema parece estar relacionado ao console.
NaturalBornCamper 20/09/19
187

Corrigi-o adicionando .encode("utf-8")a soup.

Isso significa que print(soup)se torna print(soup.encode("utf-8")).

SstrykerR
fonte
3
não codificar a codificação de caracteres do seu ambiente (por exemplo, console) dentro do seu roteiro, imprimir Unicode diretamente em vez
JFS
Isso é apenas imprimir o repr de um bytesobjeto, que será impresso como uma bagunça de \xsequências, se houver muito texto codificado em UTF-8. Eu recomendo usar win_unicode_console, como sugere o @JFSebastian.
Eryk Sun
2
Eu usei a solução acima, mas ainda estou tendo problemas: classe MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8")))) UnicodeEncodeError: 'charmap' codec can ' t codifica o caractere '\ u2019' na posição 87: mapas de caracteres para <indefinido> #
264 Vivek
2
Isso torna imprimir b'\x02x\xc2\xa9'(um objeto bytes) em vez
MilkyWay90
1
print(soup.encode("utf-8"))trabalhou para mim, mas antes que eu tive que também adicionarwith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
TheWalkingData
44

No Python 3.7, e executando o Windows 10, isso funcionou (não tenho certeza se ele funcionará em outras plataformas e / ou outras versões do Python)

Substituindo esta linha:

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

Com isso:

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

A razão pela qual está funcionando é porque a codificação é alterada para UTF-8 ao usar o arquivo, para que os caracteres em UTF-8 possam ser convertidos em texto, em vez de retornar um erro quando encontrar um caractere UTF-8 que é não suporta a codificação atual.

Sabbir Ahmed
fonte
1
print (sopa) return \ xd0 \ xbf \ xd0 \ xbe \ xd0 \ xb6 \ xd0 \ xb0 \ xd0 \ xbb \ xd1 \ x83 \ xd0 \ xb9 \ xd
Coffee inTime
12

Ao salvar a resposta da solicitação de obtenção, o mesmo erro foi lançado no Python 3.7 na janela 10. A resposta recebida da URL, a codificação foi UTF-8, portanto, é sempre recomendável verificar a codificação para que a mesma possa ser passada para evitar esse problema trivial pois realmente mata muito tempo na produção

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 adicionei encoding = "utf-8" ao comando open, ele salvou o arquivo com a resposta correta

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

Até eu enfrentei o mesmo problema com a codificação que ocorre quando você tenta imprimi-lo, lê / escreve ou abre. Como outros mencionados acima, adicionar .encoding = "utf-8" ajudará se você estiver tentando imprimi-lo.

soup.encode ("utf-8")

Se você estiver tentando abrir dados raspados e talvez gravá-los em um arquivo, abra o arquivo com (......, encoding = "utf-8")

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

Pardhu Gopalam
fonte
6

Para aqueles que ainda estão recebendo esse erro, adicionar encode("utf-8")ao souptambém corrigirá isso.

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)
Pseudo Sudo
fonte
2
soupnão é mais um BeautifulSoupobjeto depois de fazer isso de modo que não pode ser manipulado ou procurou
NaturalBornCamper