美文网首页
5. XPath 解析库

5. XPath 解析库

作者: 柄志 | 来源:发表于2018-08-23 15:36 被阅读0次

    XPath

    XPath,全称XML Path Language,即XML路径语言,它提供简洁明了的路径选择表达式,用于在 XML 文档中通过元素和属性进行导航。

    XPath常用规则

    表达式 描述
    nodename 选取此节点所有子节点
    / 从当前节点选取直接子节点
    // 从当前节点选取所有子孙节点
    . 选取当前节点
    .. 选取当前节点的父节点
    @ 选取属性

    实例HTML文档

    <div>
        <ul>
        <li class="item-0"><a href="link1.html"><span>first item</span></a></li>
        <li class="item-1"><a href="link2.html">second item</a></li>
       <li class="item-1 item-inactive" name="item"><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>
    

    子节点、父节点、文本及属性

    • Python通过lxml库,利用XPath进行HTML解析
    # 从lxml库导入etree模块
    from lxml import etree
    
    # 声明一段HTML文本
    text
        '''
        实例HTNL文档(略)
        '''
    
    # 调用HTML类进行初始化,构造XPath解析对象
    html = etree.HTML(text)
    
    # 调用tostring()方法输出修正后的HTML代码(bytes类型)
    result = etree.tostring(html)
    
    # 调用decode()方法将bytes类型的HTML代码转成str类型
    print(result.decode('utf-8'))
    
    f = open('test.html','wt',encoding = 'utf-8')
    f.write(result.decode('utf-8'))
    f.close()
    
    '''
    # 直接读取文本文件进行解析
    html = etree.parse('test.html',etree.HTMLParse())
    result = etree.tostring(html)
    print(result.decode('utf-8'))
    '''
    

    • 用//开头的XPath规则来选取所有符合要求的节点
    • 通过/或//查找元素的子节点或子孙节点
    • 通过..查找元素的父节点
    • 用@符号进行属性过滤或获取属性
    • 用text()方法获取节点中的文本
    from lxml import etree
    html = etree.parse('test.html',etree.HTMLParse())
    
     # 选取所有节点
    result = html.xpath('//*') 
    
    # 选取所有li节点的所有直接a子节点
    result = html.xpath('//li/a') 
    
    # 选取所有ul节点下所有子孙a节点
    result = html.xpath('//ul//a') 
    
    # 选中属性href为ink1.html的a节点,再选中取其父节点获取其class属性
    result = html.xpath('//a[@href="link1.html"]/../@class') 
    
    # 选取class为item-0的li节点
    result = html.xpath('//li[@class="item-0"]')
    
    # 选取属性为item-0的li节点,获取其直接子节点a的文本(以列表形式返回)
    result = html.xpath('//li[@class="item-0"]/a/text()')
    
    # 获取所有li节点所有直接a子节点的href属性(以列表形式返回)
    result = html.xpath('//li/a/@href')
    
    • 通过contains()方法进行属性多值匹配(第一个参数传入属性名称,第二个参数传入属性值)
    • 多重属性匹配根据多个属性确定一个节点,需要同时匹配多个属性,可通过and运算符来连接
    from lxml import etree
    html = etree.parse('test.html',etree.HTMLParse())
    
    '''
    <li class="item-1 item-inactive" name="item"><a href="link3.html">third item</a></li>
    '''
    
    # 匹配class属性为item-inactive的li节点并获取其直接a子节点的文本
    result = html.xpath('//li[contains(@class,"item-inactive")]/a/text()')
    
    # 匹配class属性为为item-inactive、name属性为item的li节点并获取其直接a子节点的文本
    result = html.xpath('//li[contain(@class,"item-inactive") and @name="item"]/a/text')
    
    • XPath运算符
    运算符 描述
    or
    and
    mod 计算除法的余数
    | 计算两个节点集
    + 加法
    - 减法
    * 乘法
    div 除法
    = 等于
    != 不等于
    < 小于
    <= 小于或等于
    > 大于
    >= 大于或等于

    按序选择

    • 匹配多个节点可利用中括号传入索引的方法获取特定次序的节点
    from lxml import etree
    html = etree.parse('test.html',etree.HTMLParse())
    
    # 选取匹配到的第一个li节点
    result = html.xpath('//li[1]/a/text')
    
    # 选取匹配到的最后一个li节点
    result = html.xpath('//li[last()]/a/text')
    
    # 选取匹配到的位置序号小于3的li节点
    result = html.xpath('//li[position()<3]/a/text')
    
    # 选取匹配到的倒数第三个li节点
    result = html.xpath('//li[last()-2]/a/text')
    

    节点轴选择

    XPath轴可定义相对于当前节点的节点集。

    描述
    ancestor 选取当前节点的所有先辈(父、祖父等)
    ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身
    attribute 选取当前节点的所有属性
    child 选取当前节点的所有子元素
    descendant 选取当前节点的所有后代元素(子、孙等)
    descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身
    following 选取文档中当前节点的结束标签之后的所有节点
    namespace 选取当前节点的所有命名空间节点
    parent 选取当前节点的父节点
    preceding 选取文档中当前节点的开始标签之前的所有节点
    preceding-sibling 选取当前节点之前的所有同级节点
    self 选取当前节点
    from lxml import etree
    html = etree.parse('test.html',etree.HTMLParse())
    
    '''
    <li class="item-0"><a href="link1.html"><span>first item</span></a></li>
    '''
    
    # 轴后跟两个冒号再跟节点选择器
    
    # 获取第一个li节点的所有祖先节点(html、body、div和ul)
    result = html.xpath('//li[1]/ancestor::*')
    
    # 获取第一个li节点的div祖先节点
    result = html.xpath('//li[1]/ancestor::div')
    
    # 获取第一个li节点的所有属性值
    result = html.xpath('//li[1]/attribute::*')
    
    # 获取第一个li节点href属性为link1.html的a节点
    result = html.xpath('//li[1]/child::a[@href="link1.html"]')
    
    # 获取第一个li节点的所有包含span而不包含a的子孙节点
    result = html.xpath('//li[1]/descendant::span')
    
    # 获取第一个li节点后的第二个后续节点
    result = html.xpath('//li[1]/following::*[2]')
    
    # 获取第一个li节点后的所有同级节点
    result = html.xpath('//li[1]/following-sibling::*')
    
    

    相关文章

      网友评论

          本文标题:5. XPath 解析库

          本文链接:https://www.haomeiwen.com/subject/dqhmiftx.html