首页 > 上网技巧 > 电脑小技巧 > 网页解析工具终结篇xpath语法

网页解析工具终结篇xpath语法

时间:2019-12-11 10:06 作者:QQ地带 我要评论

写在前面
山竹(难怪都说越是美丽的东西越危险,这么美的名字下竟是如此狂野)终于过去了,囤货泡面的日子真的不好受,希望天佑中华,无狂风再至!本期文章接着和大家讲一下相关网页解析工具xpath。如果大家熟悉文档路径结构的话,那么xpath绝对是一种较为容易掌握的网页解析方式,这也是小编为什麼将其放在最后一期网页解析系列文章的原因之一。小编一直觉得学东西一定要先啃掉难的,而后再去掌握简单的(或者说此时你只需要较少的时间投入便可掌握简单的知识)。废话就不多说了,下面正式开始本期文章的介绍。
 
xpath简介
XPath,全称XML Path Language ,即XML路径语言,它是一门在XML文档中查找信息的语言。XPath虽然是被设计用来搜寻XML文档,不过它也能很好地在HTML文档中工作,并且大部分浏览器也支持通过XPath 来查询节点。XPath既然叫Path,就是以路径表达式的形式来指定元素,这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。XPath选择功能十分强大,它提供了非常简洁明了的路径选择表达式。另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等。几乎所有想要定位的节点,基本可以用XPath来选择。关于xpath完整详细的介绍可以参考官方文档https://www.w3.org/TR/xpath/。
 
xpath语法主要表现为两点:节点以及到达节点的路径语法。考虑到路径语法不仅存在绝对路径,同时还有相当路径以及多条件路径,因此下面分四部分对xpath语法进行具体介绍:xpath节点、xpath基本路径、xpath轴以及xpath运算符。最后用一个例子结束文章。
 
xpath节点
在XPath中,XML文档是被作为节点树来对待的,有七种类型的节点:元素、属性、文
本、命名空间、处理指令、注释以及文档(根)节点。树的根被称为文档节点或者根节点。以下面的XML文档为例进行说明,文档如下:
 
<?xml version = "1.0" encoding = "ISO-8859-1"?>
<classroom>
    <student>
        <id>l001</id>
        <name lang="en"> marry </name>
        <age>20</age>
        <country>China</country>
    </student>
</classroom>
上面XML文档中节点包括:(文档节点)、100l (元素节点)、lang=”en”(属性节点)、marry(文本)。接着说一下节点关系,包括父(Parent)、子(Children)、同胞(Sibling)、先辈(Ancestor)、后代(Descendant)。在上面的文档中:
 
student元素是id、name、age以及country元素的父。
id、name、age以及country元素都是student元素的子。
id、name、age以及country元素都是同胞节点,拥有相同的父节点。
name元素的先辈是student元素和classroom元素。
classroom的后代是id、name、age以及country元素。
xpath基本路径选择
XPath使用路径表达式来选取XML文挡中的节点或节点集。节点是沿着路径或者步来选取的。接下来的重点是如何选取节点,下面给出一个XML文档进行分析:
 
<?xml version = "1.0" encoding = "ISO-8859-1"?>
<classroom>
    <Student>
        <id>1001</id>
        <name lang = "en">marry </name>
        <age>20</age>
        <country>China</country>
    </Student>
    <Student>
        <id>1002</id>
        <name lang = "en">jack </name>
        <age>25</age>
        <country>USA</country>
    </Student>
</classroom>
这里首先给出一下xpath中常用的一些路径选择规则:
 
表达式 描述
nodename 选择此节点下的所有节点
/ 选择当前节点下的子节点
// 选择当前节点下的所有子孙节点
. 选择当前节点
.. 选择当前节点的父节点
@ 选择属性
下面便使用这些选择规则对上文中所给出的xml文档进行选择演示。
 
路径表达式 选择结果
classroom 选取classroom元素的所有子节点
/classroom 选取根元素classroom
/classroom/student 选取属于classroom的所有student子元素
//student 选取所有student子元素,而不管它们在文档中的位置
/classroom//student 选择属于classroom元素的后代中的所有student元素,而不管它们位于classroom之下的什么位置
//@lang 选取名为lang的所有属性
上面例子实现的效果都是选取了所有符合条件的节点,然而如何选取某个特定的节点或者包含某一个指定的值的节点?这就需要用到谓语,谓语被嵌在方括号中,见下例。
 
路径表达式 选择结果
/classroom/student[1] 选取属于classroom元素的第一个student子元素
/classroom/student[last()] 选取属于classroom元素的最后一个student子元素
/classroom/student[last()-1] 选取属于classroom元素的倒数第二个student子元素
/classroom/student[position()<3] 选取最前面两个属于classroom元素的student子元素
//name[@lang] 选取所有拥有名为lang属性的name元素
//name[@lang=”en”] 选取所有name元素,且这些元素拥有值为en的lang属性
/classroom//student[age>20] 选取classroom元素的所有student元素,且其中age元素的值须大于20
/classroom//student[age>20]/name 选取classroom元素中的student元素的所有name元素,且其中的age元素值须大于20
XPath在进行节点选取时也可以使用通配符“*”匹配未知的元素所有元素,同时使用操作符|一次选取多条路径,见下例。
 
路径表达式 选择结果
/classroom/* 选取classroom元素的所有子元素
//* 选取文档中的所有元素
//name[@*] 选取所有带有属性的name元素
//student/name | //studengt/age 选取stndent元素所有name和age元素
/classroom/student/name | //age 选取属于classroom元素的student元素的所有name元素,以及文档中所有age元素
xpath轴
轴定义了所选节点与当前节点之间的树关系。在Python爬虫开发中,提取网页中信息
会遇到这种情况:首先提取到一个节点的信息,然后想在这个节点的基础上提取它的子节点或父节点,这时就会用到轴的概念。轴的存在会使提取变得更加灵活和准确。
 
在说轴的用法之前,需要了解位置路径表达式中的相对位置路径、绝对位置路径和步的
概念。位置路径可以是绝对的,也可以是相对的。绝财路径起始于正斜杠(/),而相对路径不会这样。在两种情况中,位置路径均包括一个或多个步,每个步均被斜杠分割:/step/ step/ …(绝时位置路径), step/step/…(相对位置路径)。
 
步包括:轴、节点测试、零个或者更多谓语,用来更深入地提炼所选的节点集。步的语法为:轴名称::节点测试[谓语]。下面先给出轴的语法规则。
 
轴名称 含义
child 选取当前节点的所有子元素
child 选取当前节点的父节点
ancestor 选取当前节点的所有先辈(父、祖父等)
ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身
descendant 选取当前节点的所有后代元素(子、孙等)
descendant-or-self 选取当前节点所有后代元素(子、孙等)以及当前节点本身
preceding 选取文档中当前节点的开始标记之前的所有节点
following 选取文档中当前节点的结束标记之后的所有节点
preceding-sibling 选取当前节点之前的所有同级节点
following-sibling 选取当前节点之后的所有同级节点
self 选取当前节点之后的所有同级节点
attribute 选取当前节点的所有属性
namespace 选取当前节点的所有命名空间节点
再次给出一个xml文档作为演示例子。
 
<?xml version = "1.0" encoding = "ISO-8859-1"?>
<classroom>
    <Student>
        <id>1001 </id>
        <name lang = "en">marry </name>
        <age>20</age>
        <country>China</country>
    </Student>
    <Student>
        <id>1002 </id>
        <name lang = "en">jack </name>
        <age>25</age>
        <country>USA</country>
    </Student>
    <teacher>
        <classid>l</classid>
        <name lang = "en">tom </name>
        <age>50</age>
        <country>USA</country>
    </teacher>
</classroom>
路径表达式 选择结果
选取当前classrnom节点中子元素的teacher节点 /classroom/child: :teacher
选取所有时节点的父节点 //id/parent::*
选取所有以classid为子节点的祖先节点 //classid/ancestor::*
选取classroom节点下的所有后代节点 /classroom/descendant::*
选取所有以student为父节点的id元素 //student/descendant::id
选取所有classid元素的祖先节点及本身 //classid/ancestor-or-self::*
选择/classroom/student本身及所有后代元素 /classroom/student/descendant-or-self::*
选取/classroom/teacher之前的所有同级节点,结果就是选择了所有的student 节点 /classroom/teacher/preceding-sibling::*
选取/classroom中第二个student之后的所有同级节点,结果就是选择了teacher 节点 /classroom/student[2]/following-sibling::*
xpath运算符
XPath表达式可返回节点集、字符串、逻辑值以及数字。以下给出相关的运算符。
 
运算符 定义 实例 含义
| 计算两个节点集 //student/name | //student/age 选取student元素的所有name和age元素
+,-,*,div,mod 加法,减法,乘法,除法,求余 /classroom/student[age=l9+1] 选取classroom元素的所有student 元素,且其中的age 元素的值须等于20
=,!=,<,>,<=,>= 等于,不等于,小于,大于,小于等于,大于等于 /classroom/student[age<20] 选取classroom元素的所有student元素,且其中的age元素的值须小于20
or,and 或,与 /classroom/student[age>20 and age <25] 选取classroom元素的所有student元素,其中的age元素的值须大于20,且小于25
实例
python中使用xpath需要导入lxml库,如果你尚未安装,那么可以自行谷歌,完成安装后就可以正常使用xpath选择器了。下面先给出一个html代码文本,而后演示怎么使用xpath获取数据。
 
text = """
<div>
<ul>
<li class="item-0"><a href="linkl.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="links.html">fifth item</a></li>
</ul>
</div>
"""
from lxml import etree
html = etree.HTML(text)
first_item = html.xpath('/ul/li[1]/text()')
>>> print(first_item)
first item
第一步是从lxml库中导入etree子模块,而后使用etree子模块中的HTML函数初始化网页代码,而后使用etree子模块中的xpath函数根据路径选择要素,这里小编要选择第一个li要素下的文本内容,所以这里使用/ul/li[1]首先定位到第一个li元素下,而后使用text()函数获取其中的文本内容。通过这个小例子,各位应该知道了xpath在网页解析中的快速。
 
后记
本文讲到这里就暂告一段落了,本期文章和大家聊了一下xpath语法以及lxml解析库的用法,了解了怎么使用lxml库中的xpath函数去获取网页中的相关内容。本期文章将作为网页解析工具篇的最后一篇,lxml将与beautifulsoup以及正则表达式共同成为小编网页解析的工具,也希望大家能够至少掌握一种。最后再次感谢你们的支持与鼓励,你们的陪伴是小编前进的动力!

标签: xpath
顶一下
(0)
0%
踩一下
(0)
0%

Google提供的广告