掌握XPath:安装配置、解析流程、语法和实战练习全攻略

引言

众所周知,XPath是Web开发中重要的工具之一,可以帮助我们在HTML或XML文档中快速定位和选择内容。但是对于初学者来说,XPath的安装配置、语法解析以及实际应用可能会有些困难。因此,在这篇文章中,我们将为大家提供一份全攻略,让大家轻松掌握XPath的使用方法。

从XPath的安装和环境配置开始,我们将为大家逐一介绍XPath的使用流程及其常用语法,同时配合实战练习,旨在让读者们在实践操作中逐步掌握XPath的技能。

无论你是新手还是老手,在掌握XPath的基础知识后,都可以为自己的Web开发工作提供更多便捷和效率,同时也能够更加深入地理解Web开发的一些本质概念。让我们一起来探索XPath的奥秘吧!

xpath安装与使用

安装

  • 安装lxml库

    pip install lxml -i pip源

解析流程与使用

  1. from lxml import etree

  2. # 解析本地HTML文件

  3. # parser = etree.HTMLParser(encoding="utf-8")

  4. # tree = etree.parse('./素材/豆瓣.html', parser=parser)

  5. # 解析网络HTML文件

  6. tree = etree.HTML(open('./素材/豆瓣.html', 'r', encoding='UTF-8').read())

  7. print(tree)

解析流程

  • 实例化一个etree的对象,把即将被解析的页面源码加载到该对象
  • 调用该对象的xpath方法结合着不同形式的xpath表达进行标签定位和数据提取

使用

  • 导入lxml.etree

    from lxml import etree

  • etree.parse()

    解析本地html文件

    html_tree = etree.parse('XX.html')

  • etree.HTML()(建议)

    解析网络的html字符串

    html_tree = etree.HTML(html字符串)

  • html_tree.xpath()

    使用xpath路径查询信息,返回一个列表

注意:如果lxml解析本地HTML文件报错可以按照如下添加参数

  1. parser = etree.HTMLParser(encoding="utf-8")

  2. selector = etree.parse('./lol_1.html',parser=parser)

  3. result=etree.tostring(selector)

xpath语法

XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。

  • 路径表达式

    表达式描述
    /从根节点选取。
    //从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
    ./当前节点再次进行xpath
    @选取属性。

    实例

    在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

    路径表达式结果
    /html选取根元素。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
    //li选取所有li 子元素,而不管它们在文档中的位置。
    //ul//li选择属于 ul元素的后代的所有 li元素,而不管它们位于 ul之下的什么位置。
    节点对象.xpath('./div')选择当前节点对象里面的第一个div节点
    //@href选取名为 href 的所有属性。
  • 谓语(Predicates)

    谓语用来查找某个特定的节点或者包含某个指定的值的节点。

    谓语被嵌在方括号中。

    实例

    在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

    路径表达式结果
    /ul/li[1]选取属于 ul子元素的第一个 li元素。
    /ul/li[last()]选取属于 ul子元素的最后一个 li元素。
    /ul/li[last()-1]选取属于 ul子元素的倒数第二个 li元素。
    //ul/li[position()❤️]选取最前面的两个属于 ul元素的子元素的 li元素。
    //a[@title]选取所有拥有名为 title的属性的 a元素。
    //a[@title='xx']选取所有 a元素,且这些元素拥有值为 xx的 title属性。
  • 选取未知节点

    XPath 通配符可用来选取未知的 XML 元素。

    通配符描述
    *匹配任何元素节点。 一般用于浏览器copy xpath会出现
    @*匹配任何属性节点。
    node()匹配任何类型的节点。

    实例

    在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

    路径表达式结果
    /ul/*选取 ul元素的所有子元素。
    //*选取文档中的所有元素。
    //title[@*]选取所有带有属性的 title 元素。
    //node()获取所有节点

    选取若干路径

    通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

    实例

    在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

    路径表达式结果
    //book/title | //book/price选取 book 元素的所有 title 和 price 元素。
    //title | //price选取文档中的所有 title 和 price 元素。
    /bookstore/book/title | //price选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。
  • 逻辑运算

    • 查找所有id属性等于head并且class属性等于s_down的div标签

      //div[@id="head" and @class="s_down"]
      
    • 选取文档中的所有 title 和 price 元素。

      //title | //price
      

      注意: “|”两边必须是完整的xpath路径

  • 属性查询

    • 查找所有包含id属性的div节点

      //div[@id]
      
    • 查找所有id属性等于maincontent的div标签

      //div[@id="maincontent"]
      
    • 查找所有的class属性

      //@class
      
    • //@attrName

      //li[@name="xx"]//text()  # 获取li标签name为xx的里面的文本内容
      
  • 获取第几个标签 索引从1开始

     
      
    1. tree.xpath('//li[1]/a/text()') # 获取第一个

    2. tree.xpath('//li[last()]/a/text()') # 获取最后一个

    3. tree.xpath('//li[last()-1]/a/text()') # 获取倒数第二个

  • 内容查询

    查找所有div标签下的直接子节点h1的内容

    //div/h1/text()
    
  • 属性值获取

    //div/a/@href   获取a里面的href属性值
    
  • 获取所有

    1. //* #获取所有

    2. //*[@class="xx"] #获取所有class为xx的标签

  • 获取节点内容转换成字符串

    1. c = tree.xpath('//li/a')[0]

    2. result=etree.tostring(c, encoding='utf-8')

    3. print(result.decode('UTF-8'))

 
  1. from lxml import etree

  2. # 实例化

  3. tree = etree.HTML(open('./素材/豆瓣.html', 'r', encoding='UTF-8').read())

  4. # print(tree)

  5. # / 按照路径层级 一级一级往下找

  6. a_list = tree.xpath('/html/body/div/div/div/a')

  7. # 获取a标签里的文本

  8. # a_list = tree.xpath('/html/body/div/div/div/a/text()')

  9. # print(a_list)

  10. # for a in a_list:

  11. # print(a) # <Element a at 0x1d49c8a1a08>

  12. # # print(a.text) # 获取标签中文本

  13. # # 将节点对象转换为字符串

  14. # print(etree.tostring(a, encoding='UTF-8').decode('UTF-8')) # <a href="https://www.douban.com/accounts/login?source=book" class="nav-login" rel="nofollow">登录</a>

  15. # print(type(etree.tostring(a, encoding='UTF-8').decode('UTF-8'))) # <class 'str'>

  16. # // 不考虑位置

  17. # 获取页面中的所有的a标签 无论在哪个位置

  18. # a_list = tree.xpath('//a')

  19. # print(a_list)

  20. # for a in a_list:

  21. # print(a.text) # 获取标签中文本

  22. # 将节点对象转换为字符串

  23. # print(etree.tostring(a, encoding='UTF-8').decode('UTF-8'))

  24. # print(type(etree.tostring(a, encoding='UTF-8').decode('UTF-8')))

  25. # /与//的组合使用

  26. # 获取登陆和注册

  27. # a_list = tree.xpath('/html/body/div/div/div[1]/a/text()')

  28. # print(a_list)

  29. # 获取当前路径 /html/body/div/div/div 里面的所有的a 无论位置

  30. # a_list = tree.xpath('/html/body/div/div/div//a/text()')

  31. # print(a_list)

  32. # 匹配ul下的li里面的所有的文本

  33. # li_list = tree.xpath('//ul/li//text()')

  34. # print(li_list)

  35. # 添加查找条件

  36. # li_list = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li//text()')

  37. # print(li_list)

  38. # 查找标题

  39. # title_list = tree.xpath('//div[@class="detail-frame"]/h2/a/text()')

  40. # print(title_list)

  41. # 位置查找

  42. # 获取ul下的所有的直接子li

  43. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li')

  44. # 获取第一个li

  45. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li[1]//text()')

  46. # 获取第二个li

  47. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li[2]//text()')

  48. # 倒数第一个li

  49. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li[last()]//text()')

  50. # 倒数第二个

  51. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li[last()-1]//text()')

  52. # 获取前2个

  53. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li[position()<3]//text()')

  54. # 使用列表切片

  55. # 获取第一个

  56. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li')[0].xpath('.//text()')

  57. # 获取最后一个

  58. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li')[-1].xpath('.//text()')

  59. # print(li)

  60. # ./与.//

  61. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li')[0]

  62. # text = li.xpath('.//text()') # 根据上面li的节点对象向下继续匹配

  63. # 等同于

  64. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li[1]//text()')

  65. # .代表从当前节点继续向下匹配

  66. # ./ 就是上面/的意思 一层一层往下找

  67. # .// 就是上面//的意思 无论当前想要查找的内容在当前节点的哪个位置 都进行获取

  68. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li')[0]

  69. # text = li.xpath('./div[@class="detail-frame"]/h2/a/text()') # 根据上面li的节点对象向下继续匹配

  70. # print(text)

  71. # 等同于

  72. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li[1]/div[@class="detail-frame"]/h2/a/text()')

  73. # print(li)

  74. # li = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li')[0]

  75. # 当前匹配和li节点没有关系 因为没有从当前节点往下继续匹配

  76. # text = li.xpath('//div[@class="detail-frame"]/h2/a/text()')

  77. # text = tree.xpath('//div[@class="detail-frame"]/h2/a/text()')

  78. # print(text)

  79. # 属性值获取

  80. # @属性名

  81. # 获取所有的图片

  82. # img_list = tree.xpath('//img')

  83. # 获取所有图片的src地址 也就是连接

  84. # img_list = tree.xpath('//img/@src')

  85. # print(img_list)

  86. # 获取所有超链接的href属性值

  87. # a_list = tree.xpath('//a/@href')

  88. # print(a_list)

  89. # 当前作为了解

  90. # 查找标签具有当前整个属性的节点

  91. # a_list = tree.xpath('//a[@class]')

  92. # a_list = tree.xpath('//a[@id]')

  93. # print(a_list)

  94. # a_list = tree.xpath('//@id')

  95. # print(a_list)

  96. # * 一般我们自己不写 但是复制xpath的时候会见到

  97. # 不管当前是什么标签 条件就是id为content的我就要

  98. # //*[@id="content"]/div/div[2]/ul/li[1]/div/h2/a

  99. # 逻辑运算

  100. '''

  101. <div class="a1" id="a2">div1</div>

  102. <div class="a1" id="a3">div2</div>

  103. '''

  104. # and

  105. # text = tree.xpath('//div[@class="a1" and @id="a2"]/text()')

  106. # print(text)

  107. # or

  108. # text = tree.xpath('//div[@class="a1" or @id="a2"]/text()')

  109. # print(text)

  110. # | 代码中我们去用

xpath实战练习

抓取豆瓣的标题,封面图片标签,图片的src,简介,评分

当前包含虚构类和非虚构类

匹配豆瓣图书虚构类

  1. from lxml import etree

  2. # 实例化

  3. tree = etree.HTML(open('./素材/豆瓣.html', 'r', encoding='UTF-8').read())

  4. '''

  5. 抓取封面

  6. 标题

  7. 简介

  8. '''

  9. li_list = tree.xpath('//ul[@class="cover-col-4 clearfix"]/li')

  10. for li in li_list:

  11. img = li.xpath('./a/img/@src')

  12. title = li.xpath('./div/h2/a/text()')

  13. # info1 = li.xpath('./div/p[@class="color-gray"]/text()')

  14. # info2 = li.xpath('./div/p[@class="detail"]/text()')

  15. info = li.xpath('./div/p[@class="color-gray"]/text() | ./div/p[@class="detail"]/text()')

  16. print(info)

匹配豆瓣图书非虚构类

  1. from lxml import etree

  2. # 实例化

  3. tree = etree.HTML(open('./素材/豆瓣.html', 'r', encoding='UTF-8').read())

  4. '''

  5. 抓取封面

  6. 标题

  7. 简介

  8. '''

  9. li_list = tree.xpath('//ul[@class="cover-col-4 pl20 clearfix"]/li')

  10. for li in li_list:

  11. img = li.xpath('./a/img/@src')

  12. title = li.xpath('./div/h2/a/text()')

  13. info = li.xpath('./div/p[@class="color-gray"]/text() | ./div/p[3]/text()')

  14. print(info)

整合抓取虚构类与费虚构类的数据

  1. from lxml import etree

  2. import re

  3. # 实例化

  4. tree = etree.HTML(open('./素材/豆瓣.html', 'r', encoding='UTF-8').read())

  5. '''

  6. 抓取封面

  7. 标题

  8. 简介

  9. '''

  10. li_list = tree.xpath('//ul[@class="cover-col-4 pl20 clearfix"]/li | //ul[@class="cover-col-4 clearfix"]/li')

  11. for li in li_list:

  12. img = li.xpath('./a/img/@src')[0]

  13. title = li.xpath('./div/h2/a/text()')[0]

  14. info = li.xpath('./div/p[@class="color-gray"]/text() | ./div/p[@class="detail"]/text() | ./div/p[3]/text()')

  15. info = re.sub('\s', '', ''.join(info))

  16. print(img)

  17. print(title)

  18. print(info)

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

这份文档,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

以上均可以分享,只需要你搜索vx公众号:程序员雨果,即可免费领取

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值