2012-02-18 16 views
7

stiamo migrando da un sistema contenuto in un altro e hanno tonnellate di HTML dove ci sono le linee, per esempio, in questo modo:Rimozione di nodi vuoti da HTML

<p style="text-align: justify;"><i> </i></p> 

Cerco un modo per mettere a nudo HTML con Python dove non c'è output di testo sullo schermo. Quindi una linea simile a questa sarebbe stata spogliata.

E, questo è solo uno dei MOLTI esempi di linee in cui non è presente l'output di testo. Quindi, avrei bisogno di trovarli tutti per spogliarli. Non devo preoccuparmi di immagini, film, ecc., Poiché solo il testo era possibile nel nostro vecchio sistema di gestione dei contenuti.

BTW, la stragrande maggioranza delle linee inizia con un tag p o con un tag div (ignorando gli spazi bianchi iniziali).

+0

Hmm. Che dire dei tag strutturali vuoti? (divs per l'utilizzo da parte di JavaScript, ad esempio) – Cameron

+0

Penso che avrai bisogno di un parser html per quello ... – greg0ire

risposta

3

Nel caso del HTML è un documento XML ben formato (Questo può essere fatto in un bypass pre con uno strumento come HTML-Tidy), questa trasformazione:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[not(normalize-space(.))]"/> 
</xsl:stylesheet> 

se applicato a qualsiasi tale documento XML - per esempio:

<html> 
<body> 
    Welcome. 
    <p style="text-align: justify;"><i> </i></p> 
</body> 
</html> 

produce il risultato voluto in cui ogni elemento il cui valore di stringa è vuota o è tutti gli spazi, viene eliminato:

<html> 

    <body> 
     Welcome. 


    </body> 

</html> 
1

Se sei su una macchina Unix, questo script python dovrebbe funzionare:

#!/usr/bin/python 

import sys 
import os 
import subprocess 
import tempfile 

if len(sys.argv) < 2: 
    sys.exit("usage: %s HTML_FILE" % sys.argv[0]) 

stylesheet = ''' 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:template match="*[string-length(normalize-space(.)) = 0]"/> 

     <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
     </xsl:template> 

    </xsl:stylesheet> 
''' 

stylesheet_file = tempfile.NamedTemporaryFile(suffix='.xslt') 
stylesheet_file.write(stylesheet) 
stylesheet_file.flush() 

p = subprocess.Popen("xsltproc --html %s %s" % (stylesheet_file.name, sys.argv[1]), 
     shell=True, stdout=subprocess.PIPE) 

p.wait() 
sys.stdout.write(p.stdout.read()) 
stylesheet_file.close() 
1

Nel caso in cui il file HTML non è validato XHTML, suggerisco l'installazione i pacchetti beautifulsoup4 e lxml e utilizzando il seguente script, che rimuove tutti i tag senza contenuti di testo e poi butta via righe vuote dalla uscita:

import sys 
from bs4 import BeautifulSoup, element 
def no_nl(s): 
    return str(s).replace("\r", "").replace("\n", "") 

if len(sys.argv) != 2: 
    print "Usage: %s html_file > output" % sys.argv[0] 
    sys.exit(1) 

soup = BeautifulSoup(open(sys.argv[1])) 

# first we have to get rid of all comments 
for e in soup.find_all(): 
    for x in e.children: 
     if isinstance(x, element.Comment): 
      x.replace_with("") 

for e in soup.find_all(): 
    if not len(no_nl(e.text).strip()): 
     e.extract() 

for s in str(soup).split("\n"): 
    if len(s.strip()): 
     print s 

il seguente HTML:

<html><head><title>Title</title> 
</head><body> 
<div class="abc"><div> 
<div><div><span> </span> 
</div><![CDATA[ This should vanish from output ]]> </div> 
</div></div><p class="title"> <!--blah blah blah comment to remove--> 
<p class="title"><b>Something</b> here. 
</p><p style="text-align: justify;">aaa<I> x</I><span>blah</span></p> 
<p style="text-align: justify;"><I> </I><span></span> 
<p><i><b> </b></i></p> 
<div style="text-align: justify;"><i> </i></div> 
<p class="txt">Spam, spam, lovely spam. 
<p> </p></body></html> 

viene stampato come:

<html><head><title>Title</title></head><body> 
<p class="title"><b>Something</b> here. 
</p><p style="text-align: justify;">aaa<i> x</i><span>blah</span></p> 
<p class="txt">Spam, spam, 
lovely spam.</p> 
</body></html> 
0
<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="node()[normalize-space(.)]|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
Problemi correlati