UnicodeDecodeError: o codec 'utf8' não pode decodificar o byte 0xa5 na posição 0: byte inicial inválido

188

Estou usando Python-2.6 CGIscripts, mas encontrei esse erro no log do servidor enquanto fazia isso json.dumps(),

Traceback (most recent call last):
  File "/etc/mongodb/server/cgi-bin/getstats.py", line 135, in <module>
    print json.dumps(​​__getdata())
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa5 in position 0: invalid start byte

Aqui

​__get​data()função retorna dictionary {}.

Antes de postar esta pergunta, referi -a à questão do SO.


ATUALIZAÇÕES

A linha a seguir está afetando o codificador JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Eu tenho uma correção temporária para isso

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Mas não tenho certeza se é a maneira correta de fazê-lo.

Deepak Ingole
fonte
1
Parece que você tem alguns dados de string no dicionário que não podem ser codificados / decodificados. O que há no dict?
mgilson
mestre @mgilson yup eu entendi a questão, mas Donno como lidar com isso .. dicttemlist, dict, python timestamp value
Deepak Ingole
1
@ Piloto - Na verdade não. O verdadeiro problema está enterrado em algum lugar __getdata. Não sei por que você está recebendo um personagem não decodível. Você pode tentar criar patches no dict para fazê-lo funcionar, mas na maioria das vezes eles estão apenas pedindo mais problemas. Eu tentaria imprimir o dict para ver onde está o caractere não-ascii. Em seguida, descubra como esse campo foi calculado / definido e trabalhe para trás a partir daí.
mgilson
1
Eu tive o mesmo erro ao tentar ler um arquivo .csv que continha alguns caracteres não-ascii. A remoção desses caracteres (conforme sugerido abaixo) resolveu o problema.
Dmitriy R. Starson

Respostas:

87

O erro ocorre porque existe algum caractere não-ascii no dicionário e ele não pode ser codificado / decodificado. Uma maneira simples de evitar esse erro é codificar essas cadeias com a encode()função a seguir (se afor a cadeia com caracteres não ascii):

a.encode('utf-8').strip()
Santosh Ghimire
fonte
2
Como o UTF-8 é compatível com o ASCII de 7 bits da velha escola, você deve apenas codificar tudo. Para caracteres no intervalo ASCII de 7 bits, essa codificação será um mapeamento de identidade.
Tadeusz A. Kadłubowski
29
Isso não parece muito claro. Ao importar um arquivo csv, como você usa esse código?
Dave
O mesmo problema aparece para mim ao executar uma consulta sqlalchemy, como codificaria a consulta (não possui .encode, pois não é uma string)?
c8999c 3f964f64 3/07
129

Eu mudei isso simplesmente definindo um pacote de codec diferente no read_csv()comando:

encoding = 'unicode_escape'

Por exemplo:

import pandas as pd
data = pd.read_csv(filename, encoding= 'unicode_escape')
MSalty
fonte
1
Somente se você estiver usandopandas
Valeriy
1
desculpe, isso não funcionou, eu novamente tive o mesmo erro. mas quando eu usei ('filename.csv', engine = 'python'). Isso funcionou.
basavaraj_S 28/01
117

Experimente o trecho de código abaixo:

with open(path, 'rb') as f:
  text = f.read()
Coral
fonte
7
Eu tinha em rvez de rb. obrigado pelo lembrete de adicionar b!
Paul
1
Por padrão, a openfunção tem 'r' como modo somente leitura. rbsignifica modo binário de leitura.
shiva
39

Sua string possui um asciicaractere não codificado.

Não conseguir decodificar utf-8pode acontecer se você precisar usar outras codificações no seu código. Por exemplo:

>>> 'my weird character \x96'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x96 in position 19: invalid start byte

Nesse caso, a codificação é o windows-1252que você deve fazer:

>>> 'my weird character \x96'.decode('windows-1252')
u'my weird character \u2013'

Agora que você possui Unicode, pode codificar com segurança utf-8.

JCF
fonte
1
Eu criei uma página simples que pode ajudar a estabelecer a codificação de alguns "bytes misteriosos" inesperados; tripleee.github.io/8bit
tripleee
34

Na leitura csv, adicionei um método de codificação:

import pandas as pd
dataset = pd.read_csv('sample_data.csv', header= 0,
                        encoding= 'unicode_escape')
Krishna prasad.m
fonte
16

Defina o codificador padrão na parte superior do seu código

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")
HimalayanCoder
fonte
Eu acho que python3 não tem setdefaultencoding no módulo sys!
Anwar Hossain
14

A partir de 2018-05, isso será tratado diretamente com decode, pelo menos no Python 3 .

Eu estou usando o abaixo trecho para invalid start bytee invalid continuation byteerros de tipo. Adicionando errors='ignore'corrigido para mim.

with open(out_file, 'rb') as f:
    for line in f:
        print(line.decode(errors='ignore'))
aaronpenne
fonte
1
Obviamente, isso silenciosamente descarta informações. Uma solução muito melhor é descobrir o que deveria estar lá e corrigir o problema original.
tripleee
14

Inspirado por @aaronpenne e @Soumyaansh

f = open("file.txt", "rb")
text = f.read().decode(errors='replace')
Punnerud
fonte
Eu recebi "AttributeError: 'str' objeto não tem atributo 'decodificar'". Não sabe o que deu errado?
Victor Wong
Você incluiu b na "rb"? Eb é para abrir o arquivo como formato de byte. Se você apenas usar r, é string e não inclui decodificação.
Punnerud
14

Esta solução funcionou para mim:

import pandas as pd
data = pd.read_csv("training.csv", encoding = 'unicode_escape')
shiva
fonte
11

Solução Simples:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')
Gil Baggio
fonte
3
Obrigado que ajudou!
Ruben
Prazer em ajudar @Ruben
Gil Baggio
2
Obrigado, isso me ajudou. Eu estava trabalhando em pandas. Mais uma vez obrigado
basavaraj_S 28/01
Feliz por ajudar @basavaraj_S
Gil Baggio
1
A única solução que funciona para mim de todas as apresentadas aqui.
lunesco 24/06
7

A linha a seguir está afetando o codificador JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Eu tenho uma correção temporária para isso

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Marcar isso como correto como uma correção temporária (não tenho certeza).

Deepak Ingole
fonte
5

Se os métodos acima não estiverem funcionando para você, convém alterar a codificação do próprio arquivo csv.

Usando o Excel:

  1. Abrir arquivo csv usando o Excel
  2. Navegue até a opção "Menu Arquivo" e clique em "Salvar como"
  3. Clique em "Procurar" para selecionar um local para salvar o arquivo
  4. Digite o nome do arquivo pretendido
  5. Selecione a opção CSV (delimitado por vírgula) (* .csv)
  6. Clique na caixa suspensa "Ferramentas" e clique em "Opções da Web"
  7. Na guia "Codificação", selecione a opção Unicode (UTF-8) na lista suspensa "Salvar este documento como"
  8. Salve o arquivo

Usando o bloco de notas:

  1. Abrir arquivo csv usando o bloco de notas
  2. Navegue até a opção "Arquivo"> ​​"Salvar como"
  3. Em seguida, selecione o local para o arquivo
  4. Selecione a opção Salvar como tipo como Todos os arquivos ( . )
  5. Especifique o nome do arquivo com extensão .csv
  6. Na lista suspensa "Codificação", selecione a opção UTF-8.
  7. Clique em Salvar para salvar o arquivo

Ao fazer isso, você poderá importar arquivos csv sem encontrar o UnicodeCodeError.

Zuo
fonte
2

Depois de tentar todas as soluções alternativas mencionadas, se ele ainda gerar o mesmo erro, tente exportar o arquivo como CSV (uma segunda vez, se você já tiver). Especialmente se você estiver usando o scikit learn, é melhor importar o conjunto de dados como um arquivo CSV.

Passei horas juntos, enquanto a solução era simples. Exporte o arquivo como um CSV para o diretório em que o Anaconda ou suas ferramentas classificadoras estão instaladas e tente.

Sushmita
fonte
2

Você pode usar qualquer codificação padrão do seu uso e entrada específicos.

utf-8 é o padrão.

iso8859-1 também é popular na Europa Ocidental.

por exemplo: bytes_obj.decode('iso8859-1')

veja: docs

NoamG
fonte
1
Adivinhar cegamente que a codificação provavelmente produzirá mais erros. Selecionar iso8859-1 ou cp1251 etc. sem realmente saber qual codificação o arquivo usa removerá o sintoma, mas produzirá lixo se você adivinhou errado. Se tiver apenas alguns bytes, pode levar anos para você perceber e corrigir o erro real .
tripleee 04/02