一、xpath 简介
究竟什么是 xpath 呢?简单来说,xpath 就是一种在 XML 文档中查找信息的语言
而 XML 文档就是由一系列节点构成的树,例如,下面是一份简单的 XML 文档:
<html>
<body>
<div>
<p>Hello world<p>
<a href="/home">Click here</a>
</div>
</body>
</html>
XML 文档中常见的节点包括:
- 根节点:html
- 元素节点:html、body、div、p、a
- 属性节点:href
- 文本节点:Hello world、Click here
XML 文档中常见的节点间关系包括:
- 父子:例如,<p> 和 <a> 是 <div> 的子节点,反之,也称 <div> 是 <p> 和 <a> 的父节点
- 兄弟:例如,<p> 和 <a> 称为兄弟节点
- 祖先/后代:例如,<body>、<div>、<p>、<a> 都是 <html> 的后代节点,反之,也称 <html> 是 <body>、<div>、<p>、<a> 的祖先节点
对于网页解析来说,xpath 比 re 更加方便简洁,故 Python 中也提供相应的模块 —— lxml.etree
我们可以使用 pip install lxml
命令进行安装
二、xpath 使用
在正式开始讲解 xpath 的使用方法之前,我们先来构造一个简单的 XML 文档用于测试
在一般的爬虫程序中,XML 文档就是爬取回来的网页源代码
>>> sc = \'\'\'
<html>
<head>
<meta charset="UTF-8"/>
<link rel="stylesheet" href="style/base.css"/>
<title>Example website</title>
</head>
<body>
<div id="images" class="content">
<a href="image1.html">Image1<img src="image1.jpg"/></a>
<a href="image2.html">Image2<img src="image2.jpg"/></a>
<a href="image3.html">Image3<img src="image3.jpg"/></a>
</div>
</body>
</html>
\'\'\'
1、导入模块
>>> from lxml import etree
2、构造对象
>>> html = etree.HTML(sc) # 构造 lxml.etree._Element 对象
>>> # lxml.etree._Element 对象还具有代码补全功能
>>> # 假如我们得到的 XML 文档不是规范的文档,该对象将会自动补全缺失的闭合标签
>>> # 我们可以使用 tostring() 方法将对象转化成 bytes 类型的字符串
>>> # 再使用 decode(\'utf-8\') 方法将 bytes 类型的字符串转化为 str 类型的字符串
>>> print(etree.tostring(html).decode(\'utf-8\'))
3、匹配数据
我们可以使用 xpath() 方法进行匹配
(1)xpath 匹配语法
xpath 方法接受一个满足 xpath 匹配语法的字符串作为参数
下面主要介绍一下 xpath 匹配语法:
-
/
表示子代节点,例如 /E 表示匹配根节点下的子节点中的 E 元素节点>>> test = html.xpath(\'/html/head/title\')
-
//
表示后代节点,例如 //E 表示匹配根节点下的后代节点中的 E 元素节点>>> test = html.xpath(\'//a\')
-
*
表示所有节点,例如 E/* 表示匹配 E 元素节点下的子节点中的所有节点>>> test = html.xpath(\'/html/*\')
-
text()
表示文本节点,例如 E/text() 表示匹配 E 元素节点下的子节点中的文本节点>>> test = html.xpath(\'/html/head/title/text()\')
-
@ATTR
表示属性节点,例如 E/@ATTR 表示匹配 E 元素节点下的子节点中的 ATTR 属性节点>>> test = html.xpath(\'//a/@href\')
-
谓语
用于匹配指定的标签-
指定第二个 <a> 标签
>>> test = html.xpath(\'//a[2]\')
-
指定前两个 <a> 标签
>>> test = html.xpath(\'//a[position()<=2]\')
-
指定带有 href 属性的 <a> 标签
>>> test = html.xpath(\'//a[@href]\')
-
指定带有 href 属性且值为 image1.html 的 <a> 标签
>>> test = html.xpath(\'//a[@href="image1.html"]\')
-
指定带有 href 属性且值包含 image 的 <a> 标签
>>> test = html.xpath(\'//a[contains(@href,"image")]\')
-
(2)_Element 对象
xpath 方法返回字符串或者匹配列表,匹配列表中的每一项都是 lxml.etree._Element 对象
下面主要介绍一下 _Element 对象的常用属性与方法:
我们先用 xpath 方法得到匹配列表 tests 作为测试样例,tests 中的每一项都是一个 _Element 对象
>>> test = html.xpath(\'//a[@href="image1.html"]\')
>>> obj = test[0]
tag
返回标签名
>>> obj.tag
\'a\'
attrib
返回属性与值组成的字典
>>> obj.attrib
{\'href\': \'image1.html\'}
get()
返回指定属性的值
>>> obj.get(\'href\')
\'image1.html\'
text
返回文本值
>>> obj.text
\'Image1\'
【参考资料】
【爬虫系列相关文章】