• 数据解析之Xpath解析(超详细定位)


    目录

    ​编辑

    前言

    一.Xpath介绍

    1.基本介绍

    2.HTML树状结构图

    2.节点之间的关系

    Xpath中的绝对路径与相对路径

    绝对路径

    相对路径

    二.Xpath的语法介绍

    基本定位语法

    1.元素属性定位

    2.层级属性结合定位

    3.使用谓语定位

    4.使用逻辑运算符定位

    5.使用文本定位

    6.使用部分函数定位

    三.Xpath语法验证

    在开发者工具的 Elements 中按Ctrl + F,在搜索框中输入 Xpath

    四.lxml的基本使用

     五.Xpath实战(含流程)


     

     

    b477d3a2100a419bb4526e669f5783d6.jpeg

    前言

    xpath是XML路径语言,它可以用来确定xml文档中的元素位置,通过元素路径来完成对元素的查找。HTML就是XML的一种实现方式,所以xpath是一种非常强大的定位方式
     

    一.Xpath介绍

    1.基本介绍

    XPath(XML Path Language)是一种XML的查询语言,他能在XML树状结构中寻找节点。XPath 用于在 XML 文档中通过元素和属性进行导航

    xml是一种标记语法的文本格式,xpath可以方便的定位xml中的元素和其中的属性值。lxml是python中的一个第三方模块,它包含了将html文本转成xml对象,和对对象执行xpath的功能

    2.HTML树状结构图

    beff2289cc1a095e6bc59ea153187a45.png

    HTML 的结构就是树形结构,HTML 是根节点,所有的其他元素节点都是从根节点发出的。其他的元素都是这棵树上的节点Node,每个节点还可能有属性和文本。而路径就是指某个节点到另一个节点的路线。

    2.节点之间的关系

    • 父节点(Parent): HTML 是 body 和 head 节点的父节点;

    • 子节点(Child):head 和 body 是 HTML 的子节点;

    • 兄弟节点(Sibling):拥有相同的父节点,head 和 body 就是兄弟节点。title 和 div 不是兄弟,因为他们不是同一个父节点。

    • 祖先节点(Ancestor):body 是 form 的祖先节点,爷爷辈及以上👴;

    • 后代节点(Descendant):form 是 HTML 的后代节点,孙子辈及以下👶。

     

    Xpath中的绝对路径与相对路径

    Xpath 中的绝对路径从 HTML 根节点开始算,相对路径从任意节点开始。通过开发者工具,我们可以拷贝到 Xpath 的绝对路径和相对路径代码:

    8e8c598674b0489cbad8fffa09952468.png

    但是由于拷贝出来的代码缺乏灵活性,也不全然准确。大部分情况下,都需要自己定义 Xpath 语句,因此 Xpath 语法还是有必要学习。

    绝对路径

    Xpath 中最直观的定位策略就是绝对路径。 以百度中的输入框和按钮为例,通过拷贝出来的 full Xpath:

    /html/body/div[2]/div/div/div/div/form/span/input

    这就是一个绝对路径我们可以看出,绝对路径是从根节点/html开始往下,一层层的表示 出来直到需要的节点为止。这明显不是理智的选项,因此了解以下即可,不用往心里去。

    相对路径

    除了绝对路径,Xpath 中更常用的方式是相对路径定位方法,以“//”开头。 相对路径可以从任意节点开始,一般我们会选取一个可以唯一定位到的元素开始写,可以 增加查找的准确性。

    二.Xpath的语法介绍

    基本定位语法

    表达式说明举例
    /从根节点开始选取/html/div/span
    //从任意节点开始选取//input
    .选取当前节点 
    ..选取当前节点的父节点//input/.. 会选取 input 的父节点
    @选取属性或者根据属性选取//input[@data] 选取具备 data 属性的 input 元素 //@data 选取所有 data 属性
    *通配符,表示任意节点或任意属性 

    1.元素属性定位

    1.1 根据属性名定位元素

            定位具有特定属性名的元素://*[@attribute_name]

            示例://*[@class] 会匹配所有具有 "class" 属性的元素。

    1.2 根据属性名和属性值定位元素

            定位具有特定属性名和属性值的元素://*[@attribute_name='value']

            示例://*[@id='myElement'] 会匹配 id 属性值为 "myElement" 的元素。

    1.3 根据部分属性值定位元素

            定位具有属性值包含特定文本的元素://*[contains(@attribute_name,'value')]

            示例://*[contains(@class,'active')] 会匹配 class 属性值包含 "active" 的元素。

    1.4 根据多个属性进行定位

            定位具有多个属性及其对应值的元素://*[@attribute_name_1='value_1' and   @attribute_name_2='value_2']

            示例://*[@class='active' and @data-type='button'] 会匹配同时具有 class 属性值为         "active" 和 data-type 属性值为 "button" 的元素

    2.层级属性结合定位

    2.1定位父元素下的子元素

       //父元素名/子元素名:通过指定父元素和子元素的标签名来定位元素。

    2.2 定位特定属性的父元素下的子元素

      //父元素名[@属性名='属性值']/子元素名:通过指定父元素的属性和属性值,再结合子元素的标签名来定位元素。

    示例://div[@class='container']/p 会匹配 class 属性为 "container" 的 

     元素下的所有 

     元素。

    2.3定位特定属性的父元素下的特定属性的子元素

       //父元素名[@属性名1='属性值1']/子元素名[@属性名2='属性值2']:通过指定父元素和子元素的属性条件来定位元素。

    示例://ul[@id='menu']/li[@class='active'] 会匹配 id 属性为 "menu" 的 

  • second item
  • third item
  • fourth item
  • fifth item
  • """
  • # 将html转成xml文件
  • element = etree.HTML(web_data)
  • # print(element)
  • # 获取li标签下面的a标签的href
  • links = element.xpath('//ul/li/a/@href')
  • print(links)
  • # 获取li标签下面的a标签的文本数据
  • result = element.xpath('//ul/li/a/text()')
  • print(result)
  •  五.Xpath实战(含流程)

    1. import requests
    2. from lxml import etree
    3. '''
    4. 目标:熟悉xpath解析数的方式
    5. 需求:爬取电影的名称 评分 引言 详情页的url 翻页爬取1-10页 保存到列表中
    6. 如何实现?
    7. 设计技术与需要的库 requests lxml(etree)
    8. 实现步骤
    9. 1 页面分析(一般讲数据解析模块 都是静态页面)
    10. 1.1 通过观察看网页源代码中是否有我们想要的数据 如果有就分析这个url
    11. 如果没有再通过ajax寻找接口 通过分析数据在网页源代码中
    12. 1.2 确定目标url
    13. https://movie.douban.com/top250?start=0&filter= 第一页
    14. 通过页面分析发现所有我们想要的数据都在一个div[class="info"]里面
    15. 具体实现步骤
    16. 1 获取整个网页的源码 html
    17. 2 将获取的数据源码转成一个element对象(xml)
    18. 3 通过element对象实现xpath语法 对数据进行爬取(标题 评分 引言 详情页的url)
    19. 4 保存数据 先保存到字典中-->列表中
    20. '''
    21. # 定义一个函数用来获取网页源代码
    22. def getsource(pagelink):
    23. # 请求头
    24. headers = {
    25. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    26. }
    27. # 获取源码
    28. response = requests.get(pagelink, headers=headers)
    29. response.encoding = 'utf-8'
    30. html = response.text
    31. return html
    32. # 定义一个函数用于解析我们的网页源代码并获取我们想要的数据
    33. def geteveryitem(html):
    34. element = etree.HTML(html)
    35. # 拿到[class="info"]的所有div
    36. movieitemlist = element.xpath('//li//div[@class="info"]')
    37. # print(movieitemlist,len(movieitemlist))
    38. # 定义一个列表
    39. itemlist = []
    40. for item in movieitemlist:
    41. # 定义一个字典
    42. itemdict = {}
    43. # 标题
    44. title = item.xpath('./div[@class="hd"]/a/span[@class="title"]/text()')
    45. title = "".join(title).replace("\xa0", "")
    46. # print(title)
    47. # 副标题
    48. othertitle = item.xpath('./div[@class="hd"]/a/span[@class="other"]/text()')[0].replace("\xa0", "")
    49. # print(othertitle)
    50. # 评分
    51. grade = item.xpath('./div[@class="bd"]/div[@class="star"]/span[2]/text()')[0]
    52. # print(grade)
    53. # 详情页的url
    54. link = item.xpath('div[@class="hd"]/a/@href')[0]
    55. # print(link)
    56. # 引言
    57. quote = item.xpath('div[@class="bd"]/p[@class="quote"]/span/text()')
    58. # print(quote)
    59. # list index out of range
    60. # 处理方式1 非空处理
    61. if quote:
    62. quote = quote[0]
    63. else:
    64. quote = ""
    65. # 将数据存放到字典中
    66. itemdict['title'] = ''.join(title + othertitle)
    67. itemdict['grade'] = grade
    68. itemdict['link'] = link
    69. itemdict['quote'] = quote
    70. # print(itemdict)
    71. itemlist.append(itemdict)
    72. # print(itemlist)
    73. return itemlist
    74. if __name__ == '__main__':
    75. url = 'https://movie.douban.com/top250?start=0&filter='
    76. html = getsource(url)
    77. itemlist = geteveryitem(html)
    78. print(itemlist)

    今天的分享到这里就结束了,感谢各位大大的观看,各位大大的三连是博主更新的动力,感谢谢谢谢谢谢谢谢谢各位的支持!!!!! 

    24d7148ed35847efa6c01cf346148bc4.gif

     

  • 相关阅读:
    jmeter实现webservice接口测试
    新手树莓派4B安装Supervised+Home Assistant
    FreeSWITCH添加h264编码及pcap视频提取
    【vue-9】购物车案例
    Vue学习第22天——Vuex安装使用详解及案例练习(彻底搞懂vuex)
    git在linux情况下设置git 命令高亮
    相机标定基本原理
    C#将一个文件复制到成千上百个文件夹中
    GaussDB数据库SQL系列:DROP & TRUNCATE & DELETE
    数据结构--字典树(trie)
  • 原文地址:https://blog.csdn.net/weixin_73320743/article/details/133136583