2010-07-14 1 views
0

Disons que j'ai le code HTML suivant:En utilisant lxml pour trouver l'ordre du texte et des sous-éléments

<div> 
text1 
<div> 
    t1 
</div> 
text2 
<div> 
    t2 
</div> 
text3 
</div> 

Je sais que la façon d'obtenir le texte et sous-éléments de l'englobante div en utilisant lxml.html. Mais existe-t-il un moyen d'accéder à la fois au texte et aux sous-éléments d'une manière itérative, qui préserve l'ordre? En d'autres termes, je veux savoir où le "texte libre" du div apparaît par rapport aux images. Je voudrais pouvoir savoir que "text1" apparaît avant le premier div interne, et que le texte2 apparaît entre les deux divs-internes, etc.

Répondre

2

L'interface elementtree, qui offre également lxml, soutient que - par exemple avec l'arbre de l'élément intégré dans Python 2.7:

>>> from xml.etree import ElementTree as et 
>>> x='''<div> 
... text1 
... <div> 
... t1 
... </div> 
... text2 
... <div> 
... t2 
... </div> 
... text3 
... </div>''' 
>>> t=et.fromstring(x) 
>>> for el in t.iter(): 
... print '%s: %r, %r' % (el.tag, el.text, el.tail) 
... 
div: '\ntext1\n', None 
div: '\n t1\n', '\ntext2\n' 
div: '\n t2\n', '\ntext3\n' 

En fonction de votre version de lxml/elementtree, vous devrez peut-être épeler la méthode iterator .getiterator() au lieu de .iter().

Si vous avez besoin d'un seul générateur qui sera donne des étiquettes et des textes afin, par exemple:

def elements_and_texts(t): 
    for el in t.iter(): 
     yield 'tag', el.tag 
     if el.text is not None: 
      yield 'text', el.text 
     if el.tail is not None: 
      yield 'tail', el.tail 

Cela supprime essentiellement les None s et les rendements deux triplets avec un premier élément de 'tag', 'text' ou 'tail', pour vous aider à distinguer. J'imagine que ce n'est pas votre format idéal, mais il ne devrait pas être difficile de le transformer en quelque chose de plus à votre goût ;-).

Questions connexes