IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Unicode et espace insécable


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    293
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 293
    Par défaut Unicode et espace insécable
    Bonjour à tous,


    La ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    affichage=affichage.decode("utf-8")
    provoque une erreur. En fait affichage contient un texte html et je m'aperçois que la cause de cette erreur est càd un espace insécable.

    Est-ce un problème de ma part ou est-ce que Unicode ne gère pas ce caractère?

    Par ailleurs dans le module qui lit l'url, j'ajoute:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.contenu_texte += self.re_multiplespaces.sub(' ',data.replace('\t',' ').replace('\n','').replace('\r','').replace('"','""').replace(chr(160), ' ')
    L'espace insécable est bien remplacé mais les 'à' ne sont plus affichés...

    D'avance merci à qui pouua m'aider.

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    L'espace insécable en unicode existe bien (160 ou \xA0), tu peux le vérifier facilement avec une table de caractères (Windows ou Linux).

    L'instruction "affichage.decode("utf-8")" convertit le chaine "affichage" (supposée être écrite avec l'encodage "utf-8"), en chaine encodée en unicode interne.

    Si cela génère une erreur, c'est que "affichage" n'est pas en utf-8.

    Tyrtamos

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    293
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 293
    Par défaut
    Tout d'abord merci de m'avoir répondu.


    affichage contient un texte récupéré sur wikipédia et le code source de l'url indique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    ... C'est pourquoi je ne comprends pas ce qui se passe.

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    charset=utf-8 indique simplement que le code source de la page est en utf-8 lorsqu'il est transmis au navigateur, ceci afin que le navigateur affiche correctement.

    Après, tout dépend de la façon dont tu as récupéré le texte sous Python: téléchargement direct, enregistrement sur disque, copier-coller, etc... La solution utilisée doit avoir fait une conversion cachée.

    Dis comment tu as récupéré le texte html.

    Tyrtamos

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    293
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 293
    Par défaut
    Voici une partie du script en question:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    parser = URLLister()
    		parser.feed(handle.read())        
    		parser.close()                    
     
    		self.definition=parser.contenu_texte
     
     
    class URLLister(SGMLParser):
    	""" --- URLLISTER pour wikipédia ---"""
    	def reset(self):                              
    		SGMLParser.reset(self)
    		self.in_p=0 # Si nous sommes à l'intérieur du balise <p>...</p> 
    		self.contenu_texte=''
    		self.re_multiplespaces = re.compile('\s+')  # regular expression used to remove spaces in excess
     
    	def start_p(self, attrs):    
    		if self.in_p==0:
    			print'attrs :', attrs
    			self.in_p=1
     
    	def end_p(self):
    		self.in_p=2
     
    	def handle_data(self, data):
    		if self.in_p==1:	
    			self.contenu_texte += self.re_multiplespaces.sub(' ',data.replace('\t',' ').replace('\n','').replace('\r','').replace('"','""'))
    self.contenu_texte et self.definition sont-ils en utf-8?

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data.replace('\t',' ').replace('\n','').replace('\r','').replace('"','""')
    remplace chaque caractère de tabulation ’\t’ par un blanc ’ ’,
    fait disparaître tous les caractères ’\n’ et ’\r’ (ça va donner un drôle de résultat !! )
    et remplace chaque caractère ’“’ par deux: ’”“’ (je ne vois pas dans quel but)

    data se retrouve donc composée uniquement de caractères différents de ’\t’ ’\r’ et ’\n’ + des blancs

    Lancée là dessus, re_multiplespaces.sub() trouve tous les ’\f’ et les ’\v’ (peu) et les blancs (beaucoup), et les remplace... par des blancs !

    Tarabiscoté.
    N e faut-il pas commencer par corriger ceci ?




    D’autre part, n’est-il pas dommage de se lancer dans la rédaction d’un code avec un module sgmllib et une classe SGMLParser qi sont dépréciés depuis 2.6 et ont disparu de 3.x ?
    ll doit bien y avoir une raison à cela.



    De plus, je ne vois pas quel intérêt il y a à passer par une instance de classe plutôt que par une fonction pou traiter le document HTML.

  7. #7
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour.

    Citation Envoyé par Chris33 Voir le message
    self.contenu_texte et self.definition sont-ils en utf-8?
    Désolé, mais ton code est en même temps trop compliqué pour moi et trop incomplet pour que je te donne une réponse. Il faut faciliter le travail des gens à qui tu demandes de l'aide: fais un petit code mini qui montre le problème et qu'on peut essayer chez nous par simple copier-coller.

    Par ailleurs, j'abonde dans le sens d'eyquem: le module que tu utilises est obsolète. Et ce genre de module a justement tendance à ne pas bien supporter l'unicode.

    Les problèmes d'encodage sont complexes. Voilà quelques éléments pour te donner un coup de pouce:

    - il faut coder pour laisser Python manipuler des chaines unicode en interne.

    - on convertit les chaines en unicode le plus tôt possible, et en sortie le plus tard possible.

    - les conversions d'un encodage à un autre passent toujours par l'unicode interne.

    - quand on parle d'unicode en Python, on ne parle que d'unicode interne (=UCS2 qui est une version simplifiée d'utf-16). L'utf-8 et l'utf-16 sont identifiés comme type str et non comme type unicode!

    Voilà un petit code qui convertit une chaine d'un encodage à un autre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    import sys
    def convertir(ch, codin='utf-8', codout=None):
        """convertit l'encodage d'une chaine de caractères"""
        if codout==None:
            codout = sys.stdout.encoding # = l'encodage de la console en cours
        if isinstance(ch,str):
            return ch.decode(codin).encode(codout, "replace")
        elif isinstance(ch,unicode):
            return ch.encode(codout, "replace")
        else:
            return "Erreur: ch doit etre une chaine de caracteres"
        print
    Ici, codin est l'encodage de la chaine si elle n'est pas en unicode (on met l'encodage du code source Python par defaut). Et codout est l'encodage cible, mis par défaut à sys.stdout.encoding, qui est l'encodage de la console en cours pour un affichage correct. Si le caractère à convertir n'existe pas dans l'encodage cible, il est remplacé par '?' pour éviter une erreur.

    Voilà quelques exemples d'application de la fonction convertir():

    texte = "abcéèçƩ" # =texte en utf-8
    print convertir(texte) # puisque utf-8 est ici le mode par defaut de convertir()
    print [ord(c) for c in texte]
    print

    texte = u"abcéèçƩ" # =texte en unicode
    print convertir(texte) # puisque l'unicode est detecte directement par convertir
    print [ord(c) for c in texte]
    print

    texte = u"abcéèçƩ".encode("iso-8859-1", "replace") # =texte en iso-8859-1
    print convertir(texte, 'iso-8859-1')
    print [ord(c) for c in texte]
    print

    texte = u"abcéèçƩ".encode("cp1252", "replace") # =texte en cp1252 (Windows)
    print convertir(texte, 'cp1252')
    print [ord(c) for c in texte]
    print

    texte = u"abcéèçƩ".encode("cp850", "replace") # =texte en cp850 (console DOS de Windows)
    print convertir(texte, 'cp850')
    print [ord(c) for c in texte]
    print

    Ce qui affiche:

    abcéèçƩ
    [97, 98, 99, 195, 169, 195, 168, 195, 167, 198, 169]

    abcéèçƩ
    [97, 98, 99, 233, 232, 231, 425]

    abcéèç?
    [97, 98, 99, 233, 232, 231, 63]

    abcéèç?
    [97, 98, 99, 233, 232, 231, 63]

    abcéèç?
    [97, 98, 99, 130, 138, 135, 63]

    Le code #425 est un sigma ('Ʃ') qui n'existe qu'en unicode (unicode interne, utf-8, utf-16, ...). On voit qu'il est codé différemment selon les encodages:
    - 198, 169 en utf-8
    - 425 en unicode
    - 63 = '?' dans les encodages en un octet puisque ce caractère n'existe pas dans ces encodages

    Tyrtamos

Discussions similaires

  1. [TinyMCE] tinymce espace insécable/no-break space
    Par rasdri dans le forum Bibliothèques & Frameworks
    Réponses: 1
    Dernier message: 06/02/2008, 15h12
  2. [HTML] Espace insécable sous Firefox
    Par Pierre1111 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 04/02/2008, 10h43
  3. Ecrire une espace insécable
    Par v4np13 dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 11/01/2008, 22h09
  4. [Entities] Comment insérer un espace insécable
    Par <nbweb> dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 05/04/2007, 09h26
  5. Espace insécable dans une chaine de caractères
    Par Mors_Ubyte dans le forum Access
    Réponses: 1
    Dernier message: 11/02/2006, 21h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo