前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 爬虫网页内容提取工具xpath

Python 爬虫网页内容提取工具xpath

作者头像
一墨编程学习
发布2019-05-13 18:42:04
3.1K0
发布2019-05-13 18:42:04
举报

上一节,我们详述了lxml.html的各种操作,接下来我们熟练掌握一下XPath,就可以熟练的提取网页内容了。

XPath 是什么?

XPath的全称是 XML Path Language,即XML 路径语言,是一种在XML(HTML)文档中查找信息的语言。它有4点特性:

  • XPath 使用路径表达式在 XML 文档中进行导航
  • XPath 包含一个标准函数库
  • XPath 是 XSLT 中的主要元素
  • XPath 是一个 W3C 标准

如果你依然在编程的世界里迷茫,不知道自己的未来规划,可以加入我们的Python学习扣qun:784758214,看看前辈们是如何学习的!交流经验! 自己是一名高级python开发工程师,从基础的python脚本到web开发、爬虫、django、人工智能、数据挖掘等,零基础到项目实战的资料都有整理。 送给每一位python的小伙伴!分享一些学习的方法和需要注意的小细节,这里是python学习者聚集地

点击:python技术分享

我们从网页中提取数据,主要应用前两点。

XPath 路径表达式

使用XPath我们可以很容易定位到网页中的节点,也就是找到我们关心的数据。这些路径跟电脑目录、网址的路径很相似,通过/来表示路径的深度。

XPath 标注函数库

头内建了100多个函数,当然我们提取数据用到的有限,也就不用记住全部100多个函数了。

Xpath 的节点(Node)

XPath中的核心就是节点(Node),定义了7种不同类型的节点: 元素(Element)、属性(Attribute)、文本(Text)、命名空间(Namespace)、处理指令(processing-instruction)、注释(Comment)和文档节点(Document nodes) 这些节点组成一棵节点树,树的根节点被称为文档节点。 其中注释就是html里面的注释:`` 而命名空间、处理指令和网页数据提取基本没关系,这里就不再详述。

下面我们以一个简单的html文档为例,来解释不同的节点及其关系。

<html lang="en-US">
<body>
    <div>ABC</div>
    <ul id="menu">
        <li class="item">home</li>
        <li class="item">python</li>
    </ul>
</body>
</html>

这段html中的节点有:

  • 文档节点: <html>
  • 元素节点:<li class="item">python</li>
  • 属性节点: id="menu"

XPath 节点的关系

节点间的关系完全照搬人类传宗接代的辈分关系,但只是直系关系,没有叔叔、大伯之类的旁系关系。 还是以上面的html文档为例来说明节点关系:

父(Parent)

每个元素节点(Element)及其属性都有一个父节点。 比如,body的父是html,而body是div、ul 的父亲。

子(Children)

每个元素节点可以有零个、一个或多个子。 比如,body有两个子:div,ul,而ul也有两个子:两个li。

同辈(Sibling)

同辈有相同的父辈节点。 比如,div和ul是同辈。

先辈(Ancestor)

某节点的父辈及其以上辈分的节点。 比如,li的父辈有:ul、div、body、html

后代(Descendant)

某节点的子及其子孙节点。 比如,body的后代有:div、ul、li。

XPath节点的选取

选取节点,也就是通过路径表达来实现。这是我们在网页提取数据时的关键,要熟练掌握

下表是比较有用的路径表达式:

表达式

说明

nodename

选取当前节点的名为nodename的所有子节点。

/

从根节点选取,在路径中间时表示一级路径

//

从当前节点开始选择文档中的节点,可以是多级路径

.

从当前节点开始选取

..

从父节点开始选取

@

按属性选取

接下来通过具体的示例来加深对路径表达的理解:

路径表达式

解释

/html/body/ul/li

从根节点开始依照路径选取li元素。返回多个。

//ul/li[1]

还是选取li元素,但是路径多级跳跃到ul/li。[1]表示只取第一个li。

//li[last()]

还是选取li,但路径更跳跃。[last()]表示取最后一个li元素。

//li[@class]

选取根节点的名为li且有class属性的所有后代。

//li[@class=”item”]

选择根节点的名为li且class属性为item的所有后代。

//body/*/li

选取body的名为li的孙子节点。*是通配符,表示任何节点。

//li[@*]

选取所有带属性的li元素。

//body/div `

` //body/ul

选取body的所有div和ul元素。

body/div

相对路径,选取当前节点的body元素的子元素div。绝对路径以 / 开始。

XPath函数

Xpath的函数很多,涉及到错误、数值、字符串、时间等等,然而我们从网页中提取数据的时候只会用到很少的一部分。其中最重要的就是字符串相关的函数,比如contains()函数。

contains(a, b)

如果字符串a包含字符串b,则返回true,否则返回false。 比如: contains(‘猿人学Python’, ‘Python’),返回true 那么它用在什么时候呢?我们知道,一个html标签的class是可以有多个属性值的,比如:

<div class="post-item text-red text-center">
    ...
</div>

这段html中div有三个class值,第一个表面它是一条发布的消息,后面两个是对格式做了更多的设置。如果我们想提取网页中所有发布的消息,只需要匹配到post-item 即可,这时候就可以用上contains了:

doc.xpath('//div[contains(@class, "post-item")]')

跟contains()类似的字符串匹配的函数还有:

  • starts-with(string1, string2) 判断string1是否以string2开头
  • ends-with(string1, string2) 判断string1是否以string2结尾
  • matches(string, pattern) 通过正则表达式匹配

然而,在lxml的xpath中使用ends-with(), matches() 会报错

In [232]: doc.xpath('//ul[ends-with(@id, "u")]')
---------------------------------------------------------------------------
XPathEvalError                            Traceback (most recent call last)
<ipython-input-232-79a4afc46a75> in <module>()
----> 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 竟然不支持ends-with(), matches()函数 到lxml官方网站去看看,原来它说了只支持 XPath 1.0:

lxml supports XPath 1.0, XSLT 1.0 and the EXSLT extensions through libxml2 and libxslt in a standards compliant way.

接着又在Wikipedia上找到Xpath 2.0 和 1.0 的差异对比,果然ends-with(), matches() 只属于2.0。下图中,粗体部分是1.0包含的,其它是2.0也有的:

XPath 2.0 和 1.0 的差异

好了,Xpath在网页内容提取中要用到的部分已经讲完了

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.04.29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • XPath 是什么?
  • XPath 路径表达式
  • XPath 标注函数库
  • Xpath 的节点(Node)
  • XPath 节点的关系
    • 父(Parent)
      • 子(Children)
        • 同辈(Sibling)
          • 先辈(Ancestor)
            • 后代(Descendant)
            • XPath节点的选取
            • XPath函数
              • contains(a, b)
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档