2017-09-29 2 views
-3

J'utilise Scrapy pour collecter des données d'un certain nombre de sites Web. J'utilise w3lib.html.remove_tags avec Compose dans mes déclarations ScrapyField() pour nettoyer entièrement le HTML à rien d'autre que des balises de mise en forme de base: b, em, strong, i et br. J'ai alors un pipeline pour le reconstruire en HTML plus propre et plus uniforme pour l'affichage sur un autre site Web. Une grande partie du HTML éraillé finit par avoir plusieurs balises br consécutives que je dois fusionner en une seule balise br par occurrence. La réponse acceptée à cette question: Merge multiple <br /> tags to a single one with python lxml accomplit exactement ceci, mais, seulement quand les étiquettes
ne sont pas séparées par des espaces. Supposons un de mes ItemLoaders renvoie la chaîne suivante:scrapy/lxml.html: Consolider plusieurs balises consécutives <br>

<div class="info"> <br> <br> <p class="tight"><br> Some text</p><br> <br></div> 

La solution référencé ci-dessus ne fonctionne pas sur eux. Comment est-il possible de les consolider? Je suis à la recherche d'une solution non-RegEx. Il semble que lxml devrait être capable de gérer cela, mais je ne peux pas comprendre comment.

+0

Je ne pense pas de toute solution non-regex, pourquoi vous ne voulez pas utiliser Regex? – Umair

+0

Intéressé de connaître la raison de ces downvotes. – NFB

Répondre

2

Ci-dessous le code fonctionne bien pour moi

from lxml import html 
data = """ 
<div class="info"> <br> <br> <br> <p class="tight"><br> Some text</p><br> <br></div> 
""" 
doc = html.fromstring(data) 
for br in doc.findall('.//br'): 
    if br.tail is None or br.tail.strip() =='': # no text immediately after <br> tag 
     for dup in br.itersiblings(): 
      if dup.tag != 'br': # don't merge if there is another tag inbetween 
       break 
      dup.drop_tag() 
      if not (dup.tail is None or dup.tail.strip() == ''): # don't merge if there is a text inbetween 
       break 

print(html.tostring(doc)) 

Sorties:

b'<div class="info"> <br>  <p class="tight"><br> Some text</p><br> </div>\n' 
+0

Réponse parfaite. Si simple, je ne sais pas pourquoi je n'y ai pas pensé. Je vous remercie! – NFB