我们正在从一个内容系统迁移到另一个内容系统,并且有大量的HTML,其中有行,例如,像这样:
<p style="text-align: justify;"><i> </i></p>
我正在寻找一种用Python剥离HTML的方法,其中没有文本输出到屏幕。因此,与此类似的线将被剥离。
而且,这只是没有文本输出的许多行中的一个例子。所以,我需要找到它们全部剥离。我不必担心图像,电影等,因为在旧的内容管理系统中只能使用文本。
BTW,绝大多数行都以p
标记或div
标记开头(忽略前导空格)。
答案 0 :(得分:3)
如果HTML也是一个结构良好的XML文档(这可以通过 HTML-Tidy 之类的工具预先完成),这个转换:
<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>
应用于任何此类XML文档时 - 例如:
<html>
<body>
Welcome.
<p style="text-align: justify;"><i> </i></p>
</body>
</html>
生成想要的结果,其中字符串值为空或者全部为空格的任何元素都将被删除:
<html>
<body>
Welcome.
</body>
</html>
答案 1 :(得分:2)
如果你在Unix机器上,这个python脚本应该可以工作:
#!/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()
答案 2 :(得分:2)
如果HTML文件无效XHTML,我建议安装beautifulsoup4和lxml软件包,并使用以下脚本删除没有文本内容的所有标记,然后从输出中抛出空行:
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
以下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>
打印为:
<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>
答案 3 :(得分: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>