【问题标题】:Python, search for html tags inside a file using regexPython,使用正则表达式在文件中搜索 html 标签
【发布时间】:2011-11-16 12:52:37
【问题描述】:

所以我正在做一些数据分析,我需要从数百个 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

知道如何实现吗?

【问题讨论】:

  • 日复一日,关于使用正则表达式解析 HTML 的问题不断涌现。如果你还没有阅读this :-)
  • @tchrist 比喻留下的东西告诉你如何到达那里,以免迷路。
  • @chown 明喻≠隐喻
  • @tchrist:它是来自站点根目录的路径,它告诉您如何到达正在查看的页面。类似amazon &gt; electronics &gt; game console &gt; PS3
  • @chown,并不是说我们使用的是 english.stackexchange 或其他任何东西,而是您链接到的来源说明喻使用了“like”或类似的词。您对面包屑的描述没有使用任何类型的东西。这不是一个比喻。

标签: python html regex


【解决方案1】:

html5lib 是一个非常可靠的 html 解析器。由于您的 xhtml 是 somewhat broken,因此 xml 解析器将拒绝它。幸运的是,html5lib 拥有 lxml integration,因此您仍然可以使用 lxml 和 xpath 的全部功能来提取数据。

【讨论】:

    【解决方案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')
    

    【讨论】:

    • 不幸的是,这不适用于在野网上找到的 html。
    • 如今大多数页面在 xml 解析器看来都是有效的。如果它们不是,您可以轻松地子类化一个 xml 解析器,或者 "".replace() 不是的部分(假设无效的是静态的)。
    【解决方案3】:

    使用真正的 HTML 解析器,而不是正则表达式。你会更快乐。 lxml.html 备受推崇,BeautifulSoup 也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 2015-01-05
      • 2014-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多