网页信息抓取软件(XPath的节点(Node)中的核心就是节点及其关系 )
优采云 发布时间: 2021-09-10 13:14网页信息抓取软件(XPath的节点(Node)中的核心就是节点及其关系
)
在上一节中,我们详细介绍了lxml.html的各种操作。接下来,如果我们熟练掌握XPath,就可以熟练地提取网页内容了。
什么是 XPath?
XPath 的全称是 XML Path Language,它是一种用于在 XML (HTML) 文档中查找信息的语言。它有4个特点:
我们从网页中提取数据,主要应用前两点。
XPath 路径表达式
使用XPath,我们可以轻松定位网页中的节点,即找到我们关心的数据。这些路径与计算机目录和URL的路径非常相似,路径的深度用/表示。
XPath注解函数库
标题中内置了 100 多个函数。当然,我们提取的数据量有限,所以没有必要记住100多个函数。
Xpath 节点
XPath 的核心是 Node,它定义了 7 种不同类型的节点:Element、Attribute、Text、Namespace、Processing-instruction、Comment 和 Document 节点
这些节点构成一个节点树,树的根节点称为文档节点。
注释是html中的注释:
命名空间、处理指令和网页数据提取基本无关,这里不再赘述。
下面我们以一个简单的html文档为例来说明不同的节点及其关系。
ABC
home
python
这个html中的节点是:
XPath 节点之间的关系
节点之间的关系完全抄袭了人类血统的世代关系,但只是直接关系,并没有叔叔叔叔等旁系关系。
以上面的html文档为例说明节点关系:
家长
每个元素节点(Element)及其属性都有一个父节点。
比如body的父节点是html,body是div和ul的父节点。
儿童
每个元素节点可以有零个、一个或多个子节点。
比如body有两个孩子:div和ul,ul也有两个孩子:两个li。
兄弟姐妹
兄弟姐妹具有相同的父节点。
比如div和ul是同一代。
祖先(祖先)
节点的父节点及以上节点。
比如li的父母是:ul, div, body, html
后代(Descendant)
节点的子节点及其后代。
例如body的后代是:div、ul、li。
XPath 节点的选择
选择节点,通过路径表达式实现。这是我们从网络中提取数据的关键,我们需要熟练掌握。
下表是比较有用的路径表达式:
表达式说明
节点名
选择当前节点的所有名为nodename的子节点。
/
从根节点选择,在路径中间时,表示一级路径
//
从当前节点开始选择文档中的节点,可以是多级路径
.
从当前节点中选择
...
从父节点中选择
@
按属性选择
接下来我们会通过具体的例子来加深对路径表达式的理解:
路径表达式说明
/html/body/ul/li
从根节点开始,按照路径选择 li 元素。返回多个。
//ul/li[1]
li 元素仍然被选中,但路径在多个阶段跳转到 ul/li。 [1] 表示只取第一个 li。
//li[last()]
我还是选择了li,但是路径比较曲折。 [last()] 表示取最后一个 li 元素。
//li[@class]
选择名称为 li 且具有类属性的根节点的所有后代。
//li[@class="item"]
选择名称为li,类属性为item的根节点的所有后代。
//body/*/li
选择名为 li 的 body 的孙节点。 * 是通配符,表示任意节点。
//li[@*]
选择所有具有属性的 li 元素。
//body/div | //身体/ul
选择正文的所有 div 和 ul 元素。
正文/div
相对路径,选择当前节点的body元素的子元素div。绝对路径以/开头。
XPath 函数
Xpath 有很*敏*感*词*,涉及到错误、值、字符串、时间等,但是我们在从网页中提取数据时只用到了一小部分。其中最重要的是与字符串相关的函数,例如 contains() 函数。
收录(a, b)
如果字符串 a 收录字符串 b,则返回真,否则返回假。
例如:contains(‘猿人学习Python’,‘Python’),返回true
那么什么时候使用呢?我们知道一个html标签的class可以有多个属性值,比如:
...
这个html中的div有3个class值,第一个是贴文,后两个是更多的格式设置。如果我们想提取网页中所有已发布的消息,只需要匹配post-item,那么我们可以使用contains:
doc.xpath('//div[contains(@class, "post-item")]')
还有类似contains()的字符串匹配函数:
但是在lxml的xpath中使用ends-with(),matches()会报错
In [232]: doc.xpath('//ul[ends-with(@id, "u")]')
---------------------------------------------------------------------------
XPathEvalError Traceback (most recent call last)
in ()
----> 1 doc.xpath('//ul[ends-with(@id, "u")]')
src/lxml/etree.pyx in lxml.etree._Element.xpath()
src/lxml/xpath.pxi in lxml.etree.XPathElementEvaluator.__call__()
src/lxml/xpath.pxi in lxml.etree._XPathEvaluatorBase._handle_result()
XPathEvalError: Unregistered function
lxml 不支持 end-with()、matches() 函数
去官方lxml网站看看,原来只支持XPath1.0:
lxml 以符合标准的方式通过 libxml2 和 libxslt 支持 XPath 1.0、XSLT 1.0 和 EXSLT 扩展。
然后我在维基百科上找到了 Xpath 2.0 和 1.0 的区别。果然,ends-with(),matches()只属于2.0。下图中,粗体部分由1.0收录,其他部分也由2.0收录:
好的,我们已经完成了 Xpath 将在 Web 内容提取中使用的部分的学习。下一节我们将通过实例讲解xpath的具体数据提取过程。