原文 : http://funhacks.NET /2016/05/08/使用XPath解析HTML文档/
XPath 的全称是 XML Path Language,即 XML 路径语言,它是一种在结构化文档(比如 XML 和 HTML 文档)中定位信息的语言,关于 XPath 的介绍可以参考 https://www.w3.org/TR/xpath/。
2. 语法
2.1 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 >
2.2 选取节点
下表是 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 属性的值
2.3 谓语
谓语用来查找某个特定的节点或者包含某个指定的值的节点,谓语嵌在方括号中。
路径表达式 结果 //body//a[1] 选取属于 body 子元素的第一个 a 元素 //body//a[last()] 选取属于 body 子元素的最好一个 a 元素 //a[@href] 选取所有拥有名为 href 的属性的 a 元素 //a[@href=’image2.html’] 选取所有 href 属性等于 “image2.html” 的 a 元素
3. 在 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
。