9
votes

Erreur de codage lors de l'analyse RSS avec LXML

Je veux analyser RSS avec LXML, mais je ne sais pas comment gérer avec UnicodeDecodeError? XXX PRE>

mais je reçois une erreur: p>

tree   = etree.parse(response, parser)
File "lxml.etree.pyx", line 2692, in lxml.etree.parse (src/lxml/lxml.etree.c:49594)
  File "parser.pxi", line 1500, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:71364)
  File "parser.pxi", line 1529, in lxml.etree._parseDocumentFromURL (src/lxml/lxml.etree.c:71647)
  File "parser.pxi", line 1429, in lxml.etree._parseDocFromFile (src/lxml/lxml.etree.c:70742)
  File "parser.pxi", line 975, in lxml.etree._BaseParser._parseDocFromFile (src/lxml/lxml.etree.c:67
740)
  File "parser.pxi", line 539, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etr
ee.c:63824)
  File "parser.pxi", line 625, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:64745)
  File "parser.pxi", line 559, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:64027)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 97: ordinal not in range(128)


0 commentaires

3 Réponses :


0
votes

Vous devriez probablement seulement essayer de définir le personnage encodant en dernier recours, car il est clair que le codage est basé sur le XML Prolog (si non par les en-têtes HTTP.) De toute façon, il est inutile de transmettre le codage à < code> etree.xmlParser sauf si vous voulez remplacer le codage; Donc, éloignez-vous du paramètre coding et il devrait fonctionner.

Edit: D'accord, le problème semble être avec lxml . Les travaux suivants, pour une raison quelconque: xxx


2 commentaires

Il reste toujours la même erreur lorsque je exécuterai un script sans encodage de paramètre ...; /. Pourquoi etree.xmlParser se termine avec une erreur malgré le décodage droit de passage?


Cela fonctionne maintenant, mais j'ai dû mettre à niveau LXML vers la version 2.2.8, car avec 2.2.4, je n'ai pas pu analyser l'URL distante. De plus, le code de ma question fonctionne lorsque je change ceci: arbre = etree.parse (stringio.stringio (réponse), anal erser)



4
votes

Il est souvent plus facile d'obtenir la chaîne chargée et triée pour la bibliothèque LXML, puis appelez-la, plutôt que de compter sur la fonction lxml.etree.parse () et sa difficulté à gérer les options de codage.

Ce fichier RSS particulier commence par la déclaration de codage, tout devrait simplement fonctionner: P>

import lxml.etree
import urllib2

request = urllib2.Request('http://wiadomosci.onet.pl/kraj/rss.xml')
response = urllib2.urlopen(request).read()
print [response]
        # ['<?xml version="1.0" encoding="utf-8"?>\n<feed xmlns=... <title>Wiadomo\xc5\x9bci...']

uresponse = response.decode("utf8")
print [uresponse]    
        # [u'<?xml version="1.0" encoding="utf-8"?>\n<feed xmlns=... <title>Wiadomo\u015bci...']

tree = lxml.etree.fromstring(response)
res = lxml.etree.tostring(tree)
print [res]
        # ['<feed xmlns="http://www.w3.org/2005/Atom">\n<title>Wiadomo&#347;ci...']

lres = lxml.etree.tostring(tree, encoding="latin1")
print [lres]
        # ["<?xml version='1.0' encoding='latin1'?>\n<feed xmlns=...<title>Wiadomo&#347;ci...']


# works because the 38 character encoding declaration is sliced off
print lxml.etree.fromstring(uresponse[38:])   

# throws ValueError(u'Unicode strings with encoding declaration are not supported.',)
print lxml.etree.fromstring(uresponse)


0 commentaires

45
votes

J'ai rencontré un problème similaire et cela s'avère que cela n'a rien à voir avec les codages. Ce qui se passe est celui-ci - LXML vous jette une erreur totalement indépendante. Dans ce cas, l'erreur est que la fonction .parse attend un nom de fichier ou une URL, et non une chaîne avec le contenu lui-même. Cependant, lorsqu'il tente d'imprimer l'erreur, il étouffe des caractères non-ASCII et montre que le message d'erreur déroutant complètement. Il est très malheureux et d'autres personnes ont commenté ce problème ici:

https://mailman-mail5.webfaction.com/pipetermail/lxml/2009-febrologiquement/004393.html

Heureusement, le vôtre est une solution très facile. Il suffit de remplacer .parse avec .Fromstring et vous devriez être totalement bon à partir: xxx

viens de tester cela sur ma machine et cela a fonctionné bien. J'espère que cela aide!


1 commentaires

Que vos journées soient bénies avec la beauté éternelle et l'harmonie monsieur!