2017-09-29 2 views
-3

Ich benutze Scrapy, um Daten von einer Reihe von Websites zu sammeln. Ich verwende w3lib.html.remove_tags mit Verfassen in meinen ScrapyField() - Deklarationen, um den HTML-Code vollständig zu leeren, bis auf einfache Formatierungs-Tags: b, em, strong, i und br. Ich habe dann eine Pipeline, um es in saubereres, einheitlicheres HTML für die Anzeige auf einer anderen Website wieder aufzubauen.scrapy/lxml.html: Consolidate mehrere aufeinanderfolgende <br> Tags

Viele der scrapped HTML endet mit mehreren aufeinander folgenden br-Tags, die ich zu einem einzigen br-Tag pro Auftreten zusammengeführt werden müssen. Die akzeptierte Antwort auf diese Frage: Merge multiple <br /> tags to a single one with python lxml erreicht genau dies, aber nur, wenn die
Tags nicht durch Leerzeichen getrennt sind. Angenommen, einer meiner ItemLoaders gibt die folgende Zeichenfolge zurück:

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

Die oben genannte Lösung funktioniert nicht auf ihnen. Wie ist es möglich, diese zu konsolidieren? Ich suche nach einer Nicht-RegEx-Lösung. Es scheint, dass lxml in der Lage sein sollte, damit umzugehen, aber ich kann nicht herausfinden, wie.

+0

Ich denke nicht, jeder Nicht-regex Lösung, warum Sie nicht wollen, Regex benutzen? – Umair

+0

Interessiert, den Grund für die downvotes zu kennen. – NFB

Antwort

2

Below Code funktioniert gut für mich

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)) 

Ausgänge:

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

Perfekte Antwort. So einfach, ich weiß nicht, warum ich nicht daran gedacht habe. Vielen Dank! – NFB

Verwandte Themen