Python,使用正则表达式在文件中搜索HTML标签
我正在做一些数据分析,需要从数百个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
。
有没有什么方法可以做到这一点?
3 个回答
2
因为大部分HTML其实就是XML(或者说可以很容易地调整成大多数XML解析器能识别的格式),所以我建议使用XML解析器。其实大多数专门处理HTML的Python解析器也都是XML解析器的子类。
你可以看看这个链接:Python和XML。
这里有一个不错的教程:Python XML解析器教程。
另外,xml.dom.minidom类对我个人来说非常有用。
还有一种类似的方法在这里解释:xml.etree.ElementTree。
这是来自xml.dom.minidom参考页面的一个好例子:
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模块:
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')
6
使用真正的HTML解析器,而不是正则表达式。这样你会更开心。lxml.html
和BeautifulSoup
都很受欢迎,效果很好。