使用XPath解析HTML文档

转自: 使用 XPath 解析 HTML 文档

XPath 简介

XPath 的全称是 XML Path Language,即 XML 路径语言,它是一种在结构化文档(比如 XML 和 HTML 文档)中定位信息的语言,关于 XPath 的介绍可以参考 https://www.w3.org/TR/xpath/。

语法

HTML 实例文档

后面我们将以下面的 HTML 文档介绍 XPath 的使用。

<html>
    <head>
        <base href='http://example.com/' />
        <title>Example website</title>
    </head>
    <body>
        <div id='images'>
            <a href='image1.html'>Name: My image 1 <br/><img src='image1_thumb.jpg'/></a>
            <a href='image2.html'>Name: My image 2 <br/><img src='image2_thumb.jpg'/></a>
            <a href='image3.html'>Name: My image 3 <br/><img src='image3_thumb.jpg'/></a>
            <a href='image4.html'>Name: My image 4 <br/><img src='image4_thumb.jpg'/></a>
            <a>Name: My image 5 <br/><img src='image5_thumb.jpg'/></a>
        </div>
    </body>
</html>

选取节点

下表是 XPath 常用的语法,实例对应的是上面的 HTML 文档。

表达式描述实例结果
nodename选取此节点的所有子节点body选取 body 元素的所有子节点
/从根节点选取/html选取根元素 html
//匹配选择的当前节点,不考虑位置//img选取所有 img 元素,而不管它们在文档的位置
.选取当前节点./img选取当前节点下的 img 节点
..选取当前节点的父节点../img选取当前节点的父节点下的 title
@选取属性//a[@href=”image1.html”]选取所有 href 属性为 “image1.html” 的 a 节点
//a/@href获取所有 a 节点的 href 属性的值

谓语

谓语用来查找某个特定的节点或者包含某个指定的值的节点,谓语嵌在方括号中。

路径表达式结果
//body//a[1]选取属于 body 子元素的第一个 a 元素
//body//a[last()]选取属于 body 子元素的最好一个 a 元素
//a[@href]选取所有拥有名为 href 的属性的 a 元素
//a[@href=’image2.html’]选取所有 href 属性等于 “image2.html” 的 a 元素

在 Python 中使用

python 中使用 XPath 需要安装相应的库,这里推荐使用 lxml 库。

代码示例:

# -*- coding: utf-8 -*-

from lxml import etree

html = """
<html>
    <head>
        <base href='http://example.com/' />
        <title>Example website</title>
    </head>
    <body>
        <div id='images'>
            <a href='image1.html'>Name: My image 1 <br/><img src='image1_thumb.jpg'/></a>
            <a href='image2.html'>Name: My image 2 <br/><img src='image2_thumb.jpg'/></a>
            <a href='image3.html'>Name: My image 3 <br/><img src='image3_thumb.jpg'/></a>
            <a href='image4.html'>Name: My image 4 <br/><img src='image4_thumb.jpg'/></a>
            <a>Name: My image 5 <br/><img src='image5_thumb.jpg'/></a>
        </div>
    </body>
</html>
"""

page_source = etree.HTML(html.decode('utf-8'))

title = page_source.xpath("//title/text()")
all_href = page_source.xpath("//a/@href")
a_image1_text = page_source.xpath("//body//a[1]/text()")
a_image1_src = page_source.xpath("//a[@href='image1.html']/img/@src")
a_image3_href = page_source.xpath("//a[contains(@href, '3')]/@href")
a_last = page_source.xpath("//body//a[last()]/img/@src")
all_img_src = page_source.xpath("//img/@src")

print "Title", title
print "all href", all_href
print "a_image1_text", a_image1_text
print "a_image1_src", a_image1_src
print 'a_image3_href', a_image3_href
print "a_last", a_last
print "all_img_src", all_img_src

输出结果如下:

Title ['Example website']
all href ['image1.html', 'image2.html', 'image3.html', 'image4.html']
a_image1_text ['Name: My image 1 ']
a_image1_src ['image1_thumb.jpg']
a_image3_href ['image3.html']
a_last ['image5_thumb.jpg']
all_img_src ['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']

要注意的是,如果 xpath() 找到了匹配的数据,返回的结果是一个数组,不管是一个还是多个,比如结果中的 Title

参考资料

加载评论