Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

problème d'encodage

11 réponses
Avatar
Jonathan Barnoud
Bon, je vais finir par croire que je suis un vrai boulet.
Après mon problème de redirection dont la solution était toute bête j'ai un problème
d'encodage.

J'écris mon script en utf-8 donc il comment par #_*_ coding:utf-8 _*_.
Jusque là tout va bien.
Mais le source que je récupère est (en théorie en tout cas) en iso-8858-1. Suivant
une doc que j'ai trouvé je ne sais plus où je l'ouvre avec :

import codecs
document = codecs.open( "wakka.php", "r", "iso-8859-1" )
document = document.read()
print document

Mais python me retourne le message d'erreur suivant :

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib/python2.3/encodings/iso8859_15.py", line 18, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\xb4' in position 3015:
character maps to <undefined>

Je me suis donc dit que contrairement aux indication du doctype du document, il était
peut-être en utf-8 :

import codecs
document = codecs.open( "wakka.php", "r", "utf-8" )
document = document.read()
print document

Mais :

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib/python2.3/codecs.py", line 380, in read
return self.reader.read(size)
File "/usr/lib/python2.3/codecs.py", line 253, in read
return self.decode(self.stream.read(), self.errors)[0]
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 1515-1517: invalid data

Si je passe mon script en iso-8859-1 le probleme reste entier.

Ouvrir le document sans spécifier l'encodage marche mais pose des probleme en amond.
En effet je dois parser le source html et j'utilise xml.dom.minidom qui me pose des
problèmes avec les accents :

document = open("wakka.php","r")
document = document.read()
import xml.dom.minidom
## La page contient quelques fautes au niveau de la syntaxes et la mise en grase est
gênante:
document = document.replace("&nbsp;", " ")
document = document.replace("&lt;", " ")
document = document.replace("<br >", "<br />")
document = document.replace("<br>", "<br />")
document = document.replace("<br/>", "<br />")
document = document.replace("<br />", " ")
document = document.replace("<<", "<")
document = document.replace(">>", ">")
document = document.replace("<b>", "")
document = document.replace("</b>", "")
## fin des corrections
dom = xml.dom.minidom.parseString(document)

Ce qui me renvoi :

Traceback (most recent call last):
File "<stdin>", line 2, in ?
File "/usr/lib/python2.3/xml/dom/minidom.py", line 1929, in parseString
return expatbuilder.parseString(string)
File "/usr/lib/python2.3/xml/dom/expatbuilder.py", line 940, in parseString
return builder.parseString(string)
File "/usr/lib/python2.3/xml/dom/expatbuilder.py", line 223, in parseString
parser.Parse(string, True)
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 39, column 141

Hors il s'agit du premier accent du document.
Si je rajoute ceci avant de parser :

document = document.replace("é","é")
document = document.replace("ä","ä")
document = document.replace("è","è")
document = document.replace("à","Ã ")
document = document.replace("ç","ç")
document = document.replace("ô","ô")
document = document.replace("ù","ù")
document = document.replace("ï","ï")
document = document.replace("ë","ë")
document = document.replace("´","'")
document = document.replace("É","É")
document = document.replace("ô","ô")
document = document.replace("ê","ê")
document = document.replace("û","û")
document = document.replace("î","î")
document = document.replace("â","â")

Ça marche si je suis en utf-8 mais pas si je suis en iso (et au passage il ne
remplace pas les ô...)

Mais par la suite les problèmes d'encodages se poursuivent.
Si je fais :

table = dom.getElementsByTagName("table")[2:10]
for tab in table:
line = tab.getElementsByTagName("tr")[1:]
for li in line:
cell = li.getElementsByTagName("td")[1:]
print cell[0].childNodes[0]

Python me retourne :

<DOM Text node "Seau d'eau">
<DOM Text node "Sac de fro...">
<DOM Text node "Gibier">
<DOM Text node "Bouteille ...">
Traceback (most recent call last):
File "exo2.py", line 108, in ?
print cell[0].childNodes[0]
UnicodeEncodeError: 'ascii' codec can't encode character u'\xef' in position 25:
ordinal not in range(128)

Je suis donc perplexe et désemparer. Ça semblait pourtant si simple...

Merci de votre aide,

Jonathan Barnoud

10 réponses

1 2
Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonsoir !

Le commentaire en première ligne (# -*- coding: utf-8 -*-) ne concerne pas
le code-source du script, mais la façon l'encodage interne par défaut que
Python utilisera.

Il m'étonnerait beaucoup que tu saisisses ton code en utf-8. Ou alors, il
faut me dire quel éditeur tu utilises.

Normalement, tu devrais l'ouvrir directement, sans encodage.



Pour la traduction du HTML, il ne faut pas passe par du XML, mais, plutôt,
par htmllib.HTMLParser et formatter.AbstractFormatter
(voir aussi urllib.unquote_plus).



Bonne Année
--
Michel Claveau
Avatar
Jonathan Barnoud
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle. wrote:

Il m'étonnerait beaucoup que tu saisisses ton code en utf-8. Ou alors, il
faut me dire quel éditeur tu utilises.
Scite sous linux en utf-8


Normalement, tu devrais l'ouvrir directement, sans encodage.



Pour la traduction du HTML, il ne faut pas passe par du XML, mais, plutôt,
par htmllib.HTMLParser et formatter.AbstractFormatter
(voir aussi urllib.unquote_plus).
Même pour du xhtml ? Parceque foncièrement c'est du xml...

Mais je vais jeter un coup d'oeuil la dessus.



Bonne Année
À vous aussi.


Avatar
Jonathan Barnoud
Histoire de rendre la chose encore plus incompréhenssible :
si je remplace print cell[0].childNodes[0] par print cell[0].childNodes[0].data je
n'ais aucun problème d'encodage à ce niveau là (mais avant si...).

Jonathan Barnoud
Avatar
News M Claveau /Hamster-P
Bonjour !

Je n'y connais pas grand chose à XML, mais il me semble que les outils de
Python servent plus à naviguer dans les documents, qu'à décoder un dialecte
(comme xhtml).

Et, comme xhtml, cela reste du HTML...
Avatar
Jonathan Barnoud
News M Claveau /Hamster-P wrote:
Bonjour !

Je n'y connais pas grand chose à XML, mais il me semble que les outils de
Python servent plus à naviguer dans les documents, qu'à décoder un dialecte
(comme xhtml).

Et, comme xhtml, cela reste du HTML...





Merci,
j'ai réussi à faire ce que je voulais avec xml.dom.minidom.
J'avais en effet un problème d'encodage qui venais du fait que je n'ouvrait pas le
document correctement puis que xml.dom.minidom ne reconnait pas le utf-8 seul.

En fin de compte, je récupère mon document comme ça :

def getSource(url):
import urllib2
conn=urllib2.urlopen(url)
print "téléchargement : ok"
return unicode(conn.read(), "iso-8859-1")

et je le parse comme ça :

def parseDoc(doc):
"parse le document"
import xml.dom.minidom
dom = xml.dom.minidom.parseString(doc.encode("utf-8"))
print "parse : ok"
return dom

J'avais regardé htmllib selon vos conseils mais mon anglais est très mauvais et je ne
pense pas avoir compri correctement de quoi il s'agissait.
xml.dom.minidom m'a permi de faire ce que je souhaitais c'est à dire récupérer les
données contenue dans un tableau et xhtml.

Jonathan Barnoud

Avatar
Canard Furieux
Il m'étonnerait beaucoup que tu saisisses ton code en utf-8. Ou alors, il
faut me dire quel éditeur tu utilises.


Avec SciTE par exemple...
http://scintilla.sourceforge.net/SciTE.html
Tu vas dans encoding et tu mets 'utf-8' => partique pour les regex dans des
fichiers en utf8 par exemple :-)
SciTE est une merveille pour python...

import codecs
document = codecs.open( "wakka.php", "r", "iso-8859-1" )
document = document.read()
print document


Le document est lu et encodé en unicode par python ensuite quand il fait le
mapping pour trouver le caractère correspondant dans la plage latin1 il ne
trouve pas donc il plante. La iso-8859-1 est trop restrictive essaye la
iso-8859-15 qui possède le 'oe', 'euro' etc... ou essaye cp1252 ou reste en
unicode...

Exemple
# -*- coding: iso-8859-15 -*-
a = u'u20AC' # le caractère euro en unicode
print a
Traceback (most recent call last):
File "test.py", line 2, in ?
print a
UnicodeEncodeError: 'ascii' codec can't encode character u'u20ac' in
position 0: ordinal not in range(128)

Maintenant
print a.encode( 'cp1252' )
€



De même avec xb4
a = u'xb4'
print a.encode( 'iso-8859-15' )
Traceback (most recent call last):
print a.encode( 'iso-8859-15' )
File "C:Python23libencodingsiso8859_15.py", line 18, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'xb4' in
position 0: character maps to <undefined>

Puis marche ensuite
print a.encode( 'cp1252' )
´




Avatar
Wilk
"News M Claveau /Hamster-P" writes:

Bonjour !

Je n'y connais pas grand chose à XML, mais il me semble que les outils de
Python servent plus à naviguer dans les documents, qu'à décoder un dialecte
(comme xhtml).

Et, comme xhtml, cela reste du HTML...


Si la norme est respectée, xthml c'est bien du xml pur et dur... D'où
l'intérêt d'ailleur !

--
William - http://flibuste.net

Avatar
News M Claveau /Hamster-P
Bonsoir !

Même si c'est de l'XML, le codage des accents, des espaces insécables, des
caractères particuliers (comme les chr en unicode) dépendent du dialecte
(ici xhtml), non complètement décrit par les normes XML.

Comme dans beaucoup d'autres cas, les outils XML ne pourront servir qu'au
niveau de la structure du document. Pour traiter le contenu, on peut vite
avoir besoin de compléments.

@-salutations
--
Michel Claveau
Avatar
News M Claveau /Hamster-P
Bonsoir !

Comment se comporte Scite, pour la visualisation des caractères ? (sous
windows).

Perso, j'utilise Textpad, qui permet aussi de travailler en utf-8. Mais,
même lorsque je définis une police correcte (Arial-unicode), et malgré une
mise à niveau d'uniscribe (le moteur d'affichage des caractères unicodes de
windows), j'ai qq caractères qui manquent à l'appel (notamment quelques
caractères cyrilliques, certains alphabets asiatiques et la totalité du
phénicien).

En plus, si l'on travaille en utf-8, on a intérêt à vérifier que la première
ligne du script correspond bien (pas trop de # -*- coding: cp1252 -*-)

@-salutations
--
Michel Claveau
Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonjour !

Bon, j'ai testé, rapidement, SciTE.

Résultat : utilitaire de (très) petite taille, qui se lance très rapidement.
Coloration syntaxique sympa. "Pliage" des fonctions. Codage et visualisation
en utf-8 et utf-16.
Mais : pas de macros ; ne supporte pas le copier/coller unicode ;
visualisation en utf-8 très limitée (beaucoup de caractères sont remplacés
par des carrés blancs).

Impression globale : ça me fait l'effet d'un éditeur "de poche", simple,
rapide, mais limité.


Bonne journée.
--
Michel Claveau
1 2