首页 > 编程语言 >【Python】爬虫-Xpath

【Python】爬虫-Xpath

时间:2023-02-19 18:15:34浏览次数:50  
标签:Xpath xpath item Python 爬虫 li 获取 html print

Xpath

文章参考:https://www.cnblogs.com/mxjhaima/p/13775844.html#案例

安装

pip install lxml

引用

from lxml import etree

获取文档树对象

通过Xpath 获取文档的对象,获取到对象后,可以通过文档的对象去去获取到树中的元素。

文本转化文档树对象

def strToEleObj():
    doc = '''
          <div>
              <ul>
                   <li class="item-0"><a href="link1.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="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签
               </ul>
           </div>
          '''
    # 把文本转换成一个文档树对象
    html = etree.HTML(doc)
    result = etree.tostring(html)
    print(str(result, 'utf-8'))

文件转化文档树对象

def fileToEleObj():
    # 读取外部文件 index.html
    html = etree.parse('./index.html')
    # pretty_print=True 会格式化输出
    result = etree.tostring(html, pretty_print=True)  # pretty_print=True 会格式化输出
    print(result)

节点、元素、属性、内容

xpath 的思想是通过 路径表达 去寻找节点。节点包括元素,属性,和内容

路径表达式

/   根节点,节点分隔符,
//  任意位置
.   当前节点
..  父级节点
@   属性

示例

from lxml import etree
'''
    路径表达式
'''
def get_el_list():
    doc = '''
              <div>
                  <ul>
                       <li class="item-0"><a href="link1.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="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签
                   </ul>
               </div>
              '''
    # 把文本转换成一个文档树对象
    html = etree.HTML(doc)
    # 获取当前节点
    print('获取当前节点---> ', html.xpath('.'))
    # 获取 根节点 标签 ,当前元素无根节点 通过 打印 etree.tostring(html) ,会发现根节点为 <html> </html> 包裹的内容 ,上一行获取的当前节点为 html
    print('获取 根节点 标签---> ', html.xpath('/'))
    # 获取 li 标签
    print('获取 li 标签---> ', html.xpath('//li'))
    # 获取 li 下的 a 标签属性
    print('获取li下的 a 标签属性----> ', html.xpath('//li/a/@href'))
    # 获取 p 标签 ,此标签不存在 返回结果为空数组
    print('获取 p 标签----> ', html.xpath('//p '))

输出结果

获取当前节点--->  [<Element html at 0x2a989854200>]
获取 根节点 标签--->  []
获取 li 标签--->  [<Element li at 0x2a9898ece40>, <Element li at 0x2a9899240c0>, <Element li at 0x2a989924180>, <Element li at 0x2a9899241c0>, <Element li at 0x2a989924200>]
获取li下的 a 标签属性---->  ['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
获取 p 标签---->  []

说明

  1. 将doc 转换成 文档对象后,为 包裹的内容;故获取到的当前的节点对象为HTML;
  2. 当前节点为HTML,无根节点故返回为空数组即:[];
  3. 查询不存在的节点时,返回空数组即:[]

通配符

*   任意元素
@*  任意属性
node()  任意子节点(元素,属性,内容)

示例


'''
    通配符
'''
from lxml import etree
def get_el_by_anyChar():
    doc = '''
              <div>
                  <ul class="ul" >
                       <li class="item-0"><a href="link1.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="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签
                   </ul>
               </div>
              '''
    # 把文本转换成一个文档树对象
    html = etree.HTML(doc)
    # 获取 ul 下的所有子节点
    print('获取 ul 下的所有子节点---> ', html.xpath('//ul/node()'))
    # 获取 任意元素[所有的]
    print('获取 ul 下 任意元素[所有的]---> ', html.xpath('//ul/*'))
    # 获取 任意属性 [所有的]
    print('获取 ul 下 任意属性[所有的]---> ', html.xpath('//ul/@*'))

输出结果

获取 ul 下的所有子节点--->  ['\n                       ', <Element li at 0x1d4792b5e80>, '\n                       ', <Element li at 0x1d4792b5e00>, '\n                       ', <Element li at 0x1d4792b5f00>, '\n                       ', <Element li at 0x1d4792b5f40>, '\n                       ', <Element li at 0x1d4792b5ec0>, ' 闭合标签\n                   ']
获取 任意元素--->  [<Element li at 0x1d47928dd80>, <Element li at 0x1d4792b5e80>, <Element li at 0x1d4792b5fc0>, <Element li at 0x1d4792b5e00>, <Element li at 0x1d4792b5f00>]
获取 任意属性--->  ['ul']

谓语

//a[n] n为大于零的整数,代表子元素排在第n个位置的<a>元素
//a[last()]   last()  代表子元素排在最后个位置的<a>元素
//a[last()-]  和上面同理,代表倒数第二个
//a[position()<3] 位置序号小于3,也就是前两个,这里我们可以看出xpath中的序列是从1开始
//a[@href]    拥有href的<a>元素
//a[@href='www.baidu.com']    href属性值为'www.baidu.com'的<a>元素
//book[@price>2]   price值大于2的<book>元素

示例

from lxml import etree
def get_el_by_wei():
    doc = '''
                  <div>
                      <ul class="ul" >
                           <li class="item-0"><a href="link1.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="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签
                       </ul>
                   </div>
                  '''
    # 把文本转换成一个文档树对象
    html = etree.HTML(doc)
    # 获取第一个 li / a 元素 里面的文本
    print('获取第一个 ---> ', html.xpath('//li[1]/a/text()'))
    # 获取最后一个 li / a 元素 里面的文本
    print('获取最后一个 ---> ', html.xpath('//li[last()]/a/text()'))
    # 获取倒数第二个 li / a元素 里面的文本
    print('获取 倒数第二个---> ', html.xpath('//li[last()-1]/a/text()'))
    # 获取位置序号小于3,也就是前两个 li / a元素 里面的文本
    print('获取位置序号小于3 ---> ', html.xpath('//li[position()<3]/a/text()'))
    # 获取拥有href的<a>元素下的文本
    print('获取第一个 ---> ', html.xpath('//a[@href]/text()'))
    # 获取 a 标签下 href = link3.html的a元素下的文本 注意 不是 == 而是 =
    print('获取 a 标签下 href = link3.html的<a>元素---> ', html.xpath('//a[@href="link3.html"]/text()'))
    # 获取 ul class == ul 的
    print('获取 ul class == ul  ---> ', html.xpath('//ul[@class="ul"]'))

多个路径

用| 连接两个表达式,可以进行 或匹配

//book/title | //book/price  

示例

from lxml import etree
def get_el_mutil_path():
    doc = '''
                  <div>
                      <ul class="ul" >
                           <li class="item-0"><a href="link1.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="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签
                       </ul>
                   </div>
                  '''
    # 把文本转换成一个文档树对象
    html = etree.HTML(doc)
    # 获取li 下 class = item-inactive 或者 item-1
    print('获取li 下 class = item-inactive 或者 item-1 ---> ', html.xpath('//li[@class="item-inactive"] | //li[@class="item-1"] '))

输出结果

获取li 下 class = item-inactive 或者 item-1 --->  [<Element li at 0x1b490955f40>, <Element li at 0x1b490966200>, <Element li at 0x1b490966180>]

函数

更多函数查看https://www.w3school.com.cn/xpath/xpath_functions.asp

contains(string1,string2)
starts-with(string1,string2)
# 文本
text()
# 最后一个
last()
# 位置
position()
# 回去所有节点
node()
'''
    函数
'''
from lxml import etree
def get_el_func():
    doc = '''
                     <div>
                         <ul class="ul" >
                              <li class="item-0 active"><a href="link1.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="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签
                          </ul>
                      </div>
                     '''
    # 把文本转换成一个文档树对象
    html = etree.HTML(doc)
    # 匹配 class 包含 active 的 元素
    print(html.xpath("//*[contains(@class,'active')]"))
    # 获取所有 li / a 文本
    print(html.xpath("//li/a/text()"))
    # 获取最后一个 li / a 文本
    print(html.xpath("//li[last()]/text()"))
    # 获取位置为1的li /a 文本 ,节点时从1开始 而不是0
    print(html.xpath("//li[position()=1]/a/text()"))

输出结果

[<Element li at 0x23ea36d0400>, <Element li at 0x23ea36d0180>]
['first item', 'second item', 'third item', 'fourth item', 'fifth item']
[' # 注意,此处缺少一个 ']
['first item']

标签:Xpath,xpath,item,Python,爬虫,li,获取,html,print
From: https://www.cnblogs.com/HelloWxl/p/17135233.html

相关文章

  • python方法、类方法和静态方法的区别
    classA:deff1():passdeff2(self):pass@classmethoddeff3(cls):pass@staticmethoddeff4():pass......
  • 【Python】Python实现提前查询考研成绩
    ✨Python实现提前查询考研成绩自命题院校可能会在考研成绩正式发布之前将成绩上传到研招网,并进行测试此时就可以提前查询到专业课成绩✨使用说明填写相关信息使用时......
  • python requests 最牛攻略
    目录安装ReuqestsHTTP简介什么是HTTPHTTP工作原理HTTP的9种请求方法HTTP状态码requests快速上手requests发起请求的步骤requests发起请求的两种方式请求参数发起GET......
  • 爬虫利用bs4解析练习demo
    同样也是爬取新闻页的简要信息importrequestsfrombs4importBeautifulSoupBase_url="https://news.cnblogs.com"Base_path="/n/page/"headers={"User-......
  • Python报错TypeError: 'NoneType' object is not callable
    Python报错TypeError:'NoneType'objectisnotcallable 保存内容如下  检查src文件后没有发现问题,最终在公共方法找到原因注释掉return了,取消后问题解决 ......
  • 简单的python格网算法算数据密集度demo
    #格网算法计算数据集区域数据密集度importtimeimportrandomimportnumpyasnpimportpandasaspd#模拟数据集defcreate_data():data_x=[]data_y......
  • 爬虫利用Xpath解析练习demo
    爬取新闻页的简要信息importrequestsfromlxmlimportetreefromlxml.etreeimport_ElementBase_url="https://news.cnblogs.com"Base_path="/n/page/"heade......
  • python代码规范PEP8
    1、引言本文档给出了Python编码规约,主要Python发行版中的标准库即遵守该规约。对于C代码风格的Python程序,请参阅配套的C代码风格指南。本文档和PEP257(文档字......
  • 跟着廖雪峰学python 005
    ​ 函数的调用、定义、参数 ​编辑 #######命名关键字参数没完abs()函数:绝对值>>>abs(100)100>>>abs(-20)20max()函数:接收任意多个参数,并返回最大的那个......
  • 使用python批量转换.jfif文件为.jpg
    python代码如下,有需要的自行取用:需要引入Image库,方法是:pipinstallImage importosfromPILimportImageroot_dir=r'C:\temp'deflist_files(root_dir):......