Python,使用正则表达式在文件中搜索HTML标签

2 投票
3 回答
1244 浏览
提问于 2025-04-17 02:14

我正在做一些数据分析,需要从数百个HTML和SHTML文件中提取页面标题、面包屑导航和h1标签。

这些标签的格式如下(意思是尖括号里面的内容,和面包屑导航):

<title>Mapping a Drive: Macintosh OSX &lt; Mapping a Drive &lt; eHelp &lt; Cal Poly Pomona</title>

<p><!-- InstanceBeginEditable name="breadcrumb" --><a href="../index.html">eHelp</a> &raquo; <a href="index.shtml">Mapping a Drive</a> &raquo; 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 个回答

0

html5lib 是一个非常可靠的 HTML 解析器。因为你的 XHTML 有点问题,缺少结束标签,所以普通的 XML 解析器会拒绝处理它。不过幸运的是,html5lib 可以和 lxml 结合使用,这样你仍然可以利用 lxml 和 xpath 的强大功能来提取数据。

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.htmlBeautifulSoup都很受欢迎,效果很好。

撰写回答