print - string encoding utf8 python
Peter Piper canalizó un programa de Python y perdió todos sus personajes de Unicode (3)
Tengo una secuencia de comandos de Python que carga una página web con urllib2.urlopen
, hace varios urllib2.urlopen
magia y escupe los resultados con la print
. Luego ejecutamos el programa en Windows así:
python program.py > output.htm
Aquí está el problema:
El urlopen
lee los datos de un servidor web IIS que genera UTF8. Escupe estos mismos datos a la salida, sin embargo, ciertos caracteres (como el guión largo que Word siempre inserta para usted contra su voluntad porque es más inteligente que usted) se confunde y terminan como –
lugar.
Tras una investigación adicional, noté que aunque el servidor web escupe datos UTF8, el archivo output.htm
está codificado con el conjunto de caracteres ISO-8859-1.
Mis preguntas:
- Cuando redirige un programa Python a un archivo de salida en Windows, ¿siempre usa este conjunto de caracteres?
- Si es así, ¿hay alguna manera de cambiar ese comportamiento?
- Si no, ¿hay una solución? Supongo que podría pasar
output.htm
como un parámetro de línea de comandos y escribir en ese archivo en lugar de en la pantalla, pero tendría que rehacer un montón de lógica en mi programa.
¡Gracias por cualquier ayuda!
ACTUALIZAR:
En la parte superior de output.htm
he añadido:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
Sin embargo, no hace ninguna diferencia. Los personajes siguen siendo confusos. Si cambio manualmente a UTF-8 en Firefox, el archivo se muestra correctamente. Tanto IE como FF piensan que este archivo es Western ISO aunque claramente no lo es.
Cuando canaliza un programa Python a un archivo de salida en Windows, ¿siempre usa este conjunto de caracteres?
Codificación por defecto utilizada para la salida a la tubería. En mi máquina:
In [5]: sys.getdefaultencoding()
Out[5]: ''ascii''
Si no, ¿hay una solución?
import sys
try:
sys.setappdefaultencoding(''utf-8'')
except:
sys = reload(sys)
sys.setdefaultencoding(''utf-8'')
Ahora toda la salida está codificada a ''utf-8''.
Creo que la forma correcta de manejar esta situación sin
rehacer un montón de lógica
es para decodificar todos los datos de su fuente de Internet desde el servidor o la codificación de la página a unicode
, y luego usar la solución que se muestra arriba para configurar la codificación predeterminada en utf-8
.
De sus comentarios y actualización de preguntas parece que los datos están correctamente codificados en UTF-8. Esto significa que solo necesita informarle a su navegador que es UTF-8, ya sea utilizando una lista de materiales, o mejor, agregando información de codificación a su documento HTML:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
Realmente no debería usar una declaración XML si el documento no es un XML válido.
La forma mejor y más confiable sería servir el archivo a través de HTTP y establecer el Content-Type:
apropiadamente.
La mayoría de los programas bajo Windows asumirán que estás usando la codificación predeterminada de Windows, que será ISO-8859-1 para una instalación en inglés. Esto también se aplica a la salida de la ventana de comandos. Desafortunadamente, no hay forma de establecer la codificación predeterminada en UTF-8: hay una página de códigos definida para ella, pero no está bien soportada.
Algunos editores reconocerán los caracteres de la lista de materiales al inicio del archivo y cambiarán a UTF-8, pero eso no está garantizado.
Si está generando HTML, debe incluir la etiqueta de charset
adecuada; entonces el navegador lo interpretará correctamente.