Estou retirando dados de um documento do Google, processando-os e gravando-os em um arquivo (que eventualmente colarei em uma página do Wordpress).
Possui alguns símbolos não ASCII. Como posso convertê-los com segurança em símbolos que podem ser usados na fonte HTML?
Atualmente, estou convertendo tudo para Unicode no caminho, juntando tudo em uma string Python e fazendo:
import codecs
f = codecs.open('out.txt', mode="w", encoding="iso-8859-1")
f.write(all_html.encode("iso-8859-1", "replace"))
Há um erro de codificação na última linha:
UnicodeDecodeError: o codec 'ascii' não pode decodificar o byte 0xa0 na posição 12286: ordinal fora do intervalo (128)
Solução parcial:
Este Python é executado sem erro:
row = [unicode(x.strip()) if x is not None else u'' for x in row]
all_html = row[0] + "<br/>" + row[1]
f = open('out.txt', 'w')
f.write(all_html.encode("utf-8"))
Mas se eu abrir o arquivo de texto real, vejo muitos símbolos como:
Qur’an
Talvez eu precise escrever em algo que não seja um arquivo de texto?
Respostas:
Lide exclusivamente com objetos unicode, tanto quanto possível, decodificando coisas em objetos unicode quando você os obtiver pela primeira vez e codificando-os conforme necessário na saída.
Se a sua string for realmente um objeto unicode, será necessário convertê-la em um objeto string codificado em unicode antes de gravá-la em um arquivo:
Ao ler esse arquivo novamente, você obterá uma sequência codificada em unicode que poderá decodificar em um objeto unicode:
fonte
No Python 2.6+, você pode usar
io.open()
o padrão ( embutidoopen()
) no Python 3:Pode ser mais conveniente se você precisar escrever o texto de forma incremental (não é necessário ligar
unicode_text.encode(character_encoding)
várias vezes). Ao contrário docodecs
módulo, oio
módulo possui um suporte adequado para novas linhas universais.fonte
O manuseio de strings Unicode já é padronizado no Python 3.
Você só precisa abrir o arquivo em utf-8
(a conversão Unicode de 32 bits em utf-8 de comprimento de bytes variável é automaticamente executada da memória para o arquivo).
fonte
O arquivo aberto por
codecs.open
é um arquivo que pegaunicode
dados, codificaiso-8859-1
e grava no arquivo. No entanto, o que você tenta escrever não éunicode
; você pegaunicode
e codifica emiso-8859-1
si mesmo . É isso que ounicode.encode
método faz, e o resultado da codificação de uma string unicode é uma bytestring (umstr
tipo).Você deve usar normal
open()
e codificar o unicode por conta própria ou (geralmente uma idéia melhor) usarcodecs.open()
e não codificar os dados por conta própria.fonte
Prefácio: seu visualizador funcionará?
Verifique se o visualizador / editor / terminal (no entanto, você está interagindo com o arquivo codificado utf-8) pode lê-lo. Isso costuma ser um problema no Windows , por exemplo, o Bloco de Notas.
No Python 2, use a
open
partir doio
módulo (é o mesmo que o embutidoopen
no Python 3):As práticas recomendadas, em geral, são usadas
UTF-8
para gravar arquivos (nem precisamos nos preocupar com a ordem de bytes com utf-8).O utf-8 é a codificação mais moderna e universalmente utilizável - funciona em todos os navegadores da web, na maioria dos editores de texto (veja suas configurações se houver problemas) e na maioria dos terminais / shells.
No Windows, você pode tentar
utf-16le
se estiver limitado à exibição da saída no Bloco de notas (ou em outro visualizador limitado).E basta abri-lo com o gerenciador de contexto e escrever seus caracteres unicode:
Exemplo usando muitos caracteres Unicode
Aqui está um exemplo que tenta mapear todos os caracteres possíveis com até três bits de largura (4 é o máximo, mas isso seria um pouco distante) da representação digital (em números inteiros) para uma saída imprimível codificada, juntamente com seu nome, se possível (coloque isso em um arquivo chamado
uni.py
):Isso deve ser executado na ordem de cerca de um minuto, e você pode visualizar o arquivo de dados e, se o visualizador de arquivos puder exibir unicode, você o verá. Informações sobre as categorias podem ser encontradas aqui . Com base nas contagens, provavelmente podemos melhorar nossos resultados excluindo as categorias Cn e Co, que não possuem símbolos associados a elas.
Ele exibirá o mapeamento hexadecimal, categoria , símbolo (a menos que não consiga obter o nome, provavelmente um caractere de controle) e o nome do símbolo. por exemplo
Eu recomendo
less
no Unix ou Cygwin (não imprima / copie o arquivo inteiro para sua saída):por exemplo, exibirá semelhante às seguintes linhas que eu amostramos usando Python 2 (unicode 5.2):
Meu Python 3.5 do Anaconda tem unicode 8.0, eu presumo que a maioria dos 3 teria.
fonte
Como imprimir caracteres unicode em um arquivo:
Salve isso no arquivo: foo.py:
Execute-o e envie a saída para o arquivo:
Abra o arquivo tmp.txt e olhe dentro, você vê o seguinte:
Assim, você salvou o unicode e com um sinal de ofuscação em um arquivo.
fonte
Esse erro surge quando você tenta codificar uma sequência não unicode: tenta decodificá-la, assumindo que ela esteja em ASCII simples. Existem duas possibilidades:
f.write(all_html)
vez disso..encode(...)
, ele primeiro tenta decodificá-lo.fonte
No caso de escrever em python3
No caso de escrever em python2:
Para evitar esse erro, você teria que codificá-lo em bytes usando os codecs "utf-8" como este:
e decodifique os dados durante a leitura usando os codecs "utf-8":
E também, se você tentar executar a impressão nessa string, ela decodificará automaticamente usando os codecs "utf-8" como este
fonte