所以我正在做一些数据分析,我需要从数百个HTML和SHTML文件中提取页面标题,痕迹,h1标签。
这些标签采用以下格式(意思是里面的内容和面包屑):
<title>Mapping a Drive: Macintosh OSX < Mapping a Drive < eHelp < Cal Poly Pomona</title>
<p><!-- InstanceBeginEditable name="breadcrumb" --><a href="../index.html">eHelp</a> » <a href="index.shtml">Mapping a Drive</a> » Mac OS X<!-- InstanceEndEditable --></p>
<h1><a name="contentstart" id="contentstart"></a><!-- InstanceBeginEditable name="page_heading" --><a name="top" id="top"></a>Mapping a Drive:<span class="goldletter"> Macintosh </span>OS X <!-- InstanceEndEditable --></h1>
获取这些标记后,我想进一步提取标题Mapping a Drive: Macintosh OSX
的第一部分,面包屑的最后部分Mac OS X
以及整个h1 Mapping a Drive: Macintosh OSX
知道如何实现这一目标吗?
答案 0 :(得分:6)
使用真正的HTML解析器,而不是正则表达式。你会更快乐。 lxml.html
受到高度重视,BeautifulSoup
也是如此。
答案 1 :(得分:2)
由于大多数HTML基本上都是xml(或者很容易被修剪为与大多数xml解析器兼容),我建议使用xml解析器。大多数python HTML特定的解析器无论如何都只是xml解析器的子类。
退房:Python and XML。
这是一个很好的教程:Python XML Parser Tutorial。
此外,xml.dom.minidom Class对我个人来说非常有用。
此处解释了另一种类似的方法:xml.etree.ElementTree。
这是xml.dom.minidom reference page:
的一个很好的例子import xml.dom.minidom
document = """\
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>
<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""
dom = xml.dom.minidom.parseString(document)
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)
def handleSlideshow(slideshow):
print "<html>"
handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
slides = slideshow.getElementsByTagName("slide")
handleToc(slides)
handleSlides(slides)
print "</html>"
def handleSlides(slides):
for slide in slides:
handleSlide(slide)
def handleSlide(slide):
handleSlideTitle(slide.getElementsByTagName("title")[0])
handlePoints(slide.getElementsByTagName("point"))
def handleSlideshowTitle(title):
print "<title>%s</title>" % getText(title.childNodes)
def handleSlideTitle(title):
print "<h2>%s</h2>" % getText(title.childNodes)
def handlePoints(points):
print "<ul>"
for point in points:
handlePoint(point)
print "</ul>"
def handlePoint(point):
print "<li>%s</li>" % getText(point.childNodes)
def handleToc(slides):
for slide in slides:
title = slide.getElementsByTagName("title")[0]
print "<p>%s</p>" % getText(title.childNodes)
handleSlideshow(dom)
如果您绝对必须使用正则表达式而不是解析器,请查看re module:
In [1]: import re
In [2]: grps = re.search(r"<([^>]+)>([^<]+)</\1>", "<abc>123</abc>")
In [3]: if grps:
In [4]: print grps.groups()
Out[3]: ('abc', '123')
答案 2 :(得分:0)
html5lib是一个非常可靠的html解析器。由于你的xhtml是somewhat broken,xml解析器会拒绝它。幸运的是,html5lib有lxml integration,因此您仍然可以使用lxml和xpath的全部功能来提取数据。