Estou tentando trabalhar com um conjunto de dados muito grande que contém alguns caracteres fora do padrão. Preciso usar Unicode, de acordo com as especificações do trabalho, mas estou perplexo. (E muito possivelmente fazendo tudo errado.)
Eu abro o CSV usando:
15 ncesReader = csv.reader(open('geocoded_output.csv', 'rb'), delimiter='\t', quotechar='"')
Então, tento codificá-lo com:
name=school_name.encode('utf-8'), street=row[9].encode('utf-8'), city=row[10].encode('utf-8'), state=row[11].encode('utf-8'), zip5=row[12], zip4=row[13],county=row[25].encode('utf-8'), lat=row[22], lng=row[23])
Estou codificando tudo, exceto lat e lng porque eles precisam ser enviados para uma API. Quando executo o programa para analisar o conjunto de dados no que posso usar, obtenho o seguinte Traceback.
Traceback (most recent call last):
File "push_into_db.py", line 80, in <module>
main()
File "push_into_db.py", line 74, in main
district_map = buildDistrictSchoolMap()
File "push_into_db.py", line 32, in buildDistrictSchoolMap
county=row[25].encode('utf-8'), lat=row[22], lng=row[23])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)
Acho que devo dizer que estou usando o python 2.7.2, e isso faz parte de um aplicativo desenvolvido no django 1.4. Eu li vários posts sobre este tópico, mas nenhum deles parece se aplicar diretamente. Qualquer ajuda será muito apreciada.
Você também pode querer saber se alguns dos caracteres não padrão que causam o problema são Ñ e possivelmente É.
Respostas:
Unicode não é igual a UTF-8. O último é apenas uma codificação para o primeiro.
Você está fazendo isso da maneira errada. Você está lendo dados codificados em UTF-8 , portanto, é necessário decodificar a String codificada em UTF-8 em uma string Unicode.
Portanto, basta substituir
.encode
por.decode
e deve funcionar (se o seu .csv for codificado em UTF-8).Nada para se envergonhar, no entanto. Aposto que 3 em 5 programadores tiveram problemas para entender isso, se não mais;)
Atualização: se os seus dados de entrada não forem codificados em UTF-8, você precisará
.decode()
usar a codificação apropriada, é claro. Se nada for fornecido, o python assume ASCII, o que obviamente falha em caracteres não ASCII.fonte
.decode('utf-8')
deve servir, né ?Basta adicionar estas linhas aos seus códigos:
fonte
para usuários do Python 3. você pode fazer
funciona com o frasco também :)
fonte
O principal motivo do erro é que a codificação padrão assumida pelo python é ASCII. Portanto, se os dados da string a serem codificados por
encode('utf8')
contiverem caracteres fora do intervalo ASCII, por exemplo, para uma string como 'hgvcj 터 파크 387', o python geraria um erro porque a string não está no formato de codificação esperado.Se você estiver usando a versão python anterior à versão 3.5, uma correção confiável seria definir a codificação padrão assumida pelo python para
utf8
:Dessa forma, o python seria capaz de antecipar caracteres dentro de uma string fora do intervalo ASCII.
No entanto, se você estiver usando o python versão 3.5 ou superior, a função reload () não está disponível, então você terá que corrigi-lo usando decodificar, por exemplo
fonte
Para usuários do Python 3:
mudar a codificação de 'ascii' para 'latin1' funciona.
Além disso, você pode tentar encontrar a codificação automaticamente lendo os 10.000 bytes principais usando o snippet abaixo:
fonte
Meu computador tinha o local errado definido.
Eu fiz primeiro
locale.getpreferredencoding(False)
é a função chamada poropen()
quando você não fornece uma codificação . A saída deve ser'UTF-8'
, mas neste caso é alguma variante do ASCII .Então eu executei o comando bash
locale
e obtive esta saídaEntão, eu estava usando a localidade padrão do Ubuntu, que faz com que o Python abra arquivos como ASCII em vez de UTF-8. Eu tive que definir minha localidade para
en_US.UTF-8
Se você não pode alterar a localidade do sistema, você pode invocar todo o seu código Python assim:
ou faça
para configurá-lo no shell em que você o executa.
fonte
se você tiver esse problema ao executar o certbot ao criar ou renovar o certificado, use o seguinte método
grep -r -P '[^\x00-\x7f]' /etc/apache2 /etc/letsencrypt /etc/nginx
Esse comando encontrou o caractere ofensivo "´" em um arquivo .conf no comentário. Depois de removê-lo (você pode editar os comentários como desejar) e recarregar o nginx, tudo funcionou novamente.
Fonte: https://github.com/certbot/certbot/issues/5236
fonte
Ou quando você lida com texto em Python, se for um texto Unicode, observe que é Unicode.
Defina
text=u'unicode text'
apenastext='unicode text'
.Isso funcionou no meu caso.
fonte
aberto com codificação UTF 16 por causa de latitude e longitude.
fonte
Ele funciona apenas tomando o argumento 'rb' ler binário em vez de 'r' ler
fonte