zoukankan      html  css  js  c++  java
  • xpath总结

    Python包

    pip install lxml
    

      在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。

    xpath语法

    / 代表根路径, 在下面的实例中能够找到/html, 找不到/body

    from lxml import etree
    html = """<!DOCTYPE html>
    <html>
        <head lang="en">
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <ul>
                <li class="item-"><a id='i1' href="link.html">first item</a></li>
                <li class="item-0"><a id='i2' href="llink.html">first item</a></li>
                <li class="item-1"><a href="llink2.html">second item<span>vv</span></a></li>
            </ul>
            <div><a href="llink2.html">second item</a></div>
        </body>
    </html>
    """
    
    page = etree.HTML(html)
    a = page.xpath("/html")
    b = page.xpath("/body")
    print(a) # [<Element html at 0x1e9c3aa4508>]
    print(b) # []
    

    // 代表任何路径, 在下面的例子中,我们甚至可以选到li标签

    from lxml import etree
    html = """<!DOCTYPE html>
    <html>
        <head lang="en">
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <ul>
                <li class="item-"><a id='i1' href="link.html">first item</a></li>
                <li class="item-0"><a id='i2' href="llink.html">first item</a></li>
                <li class="item-1"><a href="llink2.html">second item<span>vv</span></a></li>
            </ul>
            <div><a href="llink2.html">second item</a></div>
            <a>我是直属body的</a>
        </body>
    </html>
    """
    
    page = etree.HTML(html)
    a = page.xpath("//li")
    print(a)
    

    /可以嵌套使用,如下实例

    from lxml import etree
    html = """<!DOCTYPE html>
    <html>
        <head lang="en">
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <ul>
                <li class="item-"><a id='i1' href="link.html">first item</a></li>
                <li class="item-0"><a id='i2' href="llink.html">first item</a></li>
                <li class="item-1"><a href="llink2.html">second item<span>vv</span></a></li>
            </ul>
            <div><a href="llink2.html">second item</a></div>
        </body>
    </html>
    """
    
    page = etree.HTML(html)
    a = page.xpath("//a")
    b = page.xpath("//div/a")
    print(a) # 他有4个
    print(b) # 而div下的只有一个
    

     .和..分别是当前节点和当前节点的父节点

    from lxml import etree
    html = """<!DOCTYPE html>
    <html>
        <head lang="en">
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <ul>
                <li class="item-"><a id='i1' href="link.html">first item</a></li>
                <li class="item-0"><a id='i2' href="llink.html">first item</a></li>
                <li class="item-1"><a href="llink2.html">second item<span>vv</span></a></li>
            </ul>
            <div><a href="llink2.html">second item</a></div>
        </body>
    </html>
    """
    
    page = etree.HTML(html)
    a = page.xpath("//ul")
    print(a[0].xpath("./li")) # 在ul下可以找到3个li
    print(a[0].xpath("../li")) # 而在ul的父标签下找不到li
    print(a[0].xpath("../div")) # 但是却可以找到div
    

    66的中括号, 说出来你可能不信. 这个中括号可以根据索引取, 根据属性取, 还不是一般的索引和属性

    还是用上面的那个html

    a = page.xpath("//li[1]/a/text()") # 取第一个
    a = page.xpath("//li[last()]/a/text()") # 取最后一个
    a = page.xpath("//li[last()-1]/a/text()") # 取倒数第二个, 减几都行
    
    # 上面是取固定的, 下面是按范围
    a = page.xpath("//li[position()<3]/a/text()") # 小于3的前两个
    
    # [@attr] 可以按照属性取值
    a = page.xpath("//li[@class]/a/text()") # 这样三个就都取出来了
    a = page.xpath("//li[@class='item-0']/a/text()") # 只取出来固定属性的
    
    # 甚至可以按照元素值的大小来查找
    '''
    <li class="item-"> <count>88</count> <a id='i1' href="link.html">first item</a></li>
    <li class="item-0"><count>77</count> <a id='i2' href="llink.html">first item2</a></li>
    <li class="item-1"><count>66</count> <a href="llink2.html">second item<span>vv</span></a></li>
    '''
    a = page.xpath("//li[count>68]/a/text()") # 查询子标签里的count标签里的文本大于68的
    

    []里还可以放函数

    from lxml import etree
    html = """<!DOCTYPE html>
    <html>
        <head lang="en">
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <ul>
                <li class="item-"> <count>88</count> <a id='i1' href="link.html">first item</a></li>
                <li class="item-0"><count>77</count> <a id='i2' href="llink.html">first item2</a></li>
                <li class="item-1"><count>66</count> <a href="llink2.html">second item<span>vv</span></a></li>
            </ul>
            <ul>
                <li class="test-"> <count>88</count> <a id='i1' href="link.html">first item</a></li>
                <li class="test-0"><count>77</count> <a id='i2' href="llink.html">first item2</a></li>
                <li class="test-1"><count>66</count> <a href="llink2.html">second item<span>vv</span></a></li>
            </ul>
            
            <div><a href="llink2.html">second item</a></div>
        </body>
    </html>
    """
    
    page = etree.HTML(html)
    a = page.xpath("//li[starts-with(@class,'test')]/@class") # class以test开头的
    print(a)
    
    a = page.xpath("//li[contains(@class,'1')]/@class") # class里包含1的
    print(a)
    
    a = page.xpath("//a[contains(text(),'item2')]/text()") # a标签的内容包含item2的
    print(a)
    
    # []里的and关系
    a = page.xpath("//a[contains(text(),'item2') and @href='llink.html']/text()")
    print(a)

    其中还包括通配符

    *表示任意节点,@*表示任何属性, node()表示任意节点

    a = page.xpath("//*/a/text()") # 所有的a标签都选出来了, 不管是div下的a还是li下的a
    a = page.xpath("//*/a[@*]/text()") # 这也是所有a, 你要是不服就把@*换成@id
    a = page.xpath("//ul/node()") # 里面包括文本节点(换行符之类的)

    选取多个路径

    a = page.xpath("//ul | //div") # ul或div
    

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

    语法

    轴名称::选择语句
    轴名称 结果
    ancestor 选选取当前节点的所有先辈(父、祖父等)。
    ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
    attribute  选取当前节点的所有属性。
    child  选取当前节点的所有子元素。
    descendant 选取当前节点的所有后代元素(子、孙等)。
    descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
    namespace  选取当前节点的所有命名空间节点
    parent 选取当前节点的父节点。
    preceding 选取文档中当前节点的开始标签之前的所有节点。
    preceding-sibling  选取当前节点之前的所有同级节点。
    self 选取当前节点。
    following 选取文档中当前节点的结束标签之后的所有节点。

    示例:
     就随便来俩吧

    a = page.xpath("//ul/child::li") # ul的子标签
    a = page.xpath("//ul/li/child::a/attribute::href") # 取到href属性的值
    

    取值

    上卖我们一直用text()来取某个标签的文本, 下面来介绍其他几种

    通过string取文本

    page = etree.HTML(html)
    a = page.xpath("string(//ul/li)")
    print(a)
    
    a = page.xpath("//ul/li")
    for i in a:
        print(i.xpath("string(.)"))
    

    通过@attr取属性

    a = page.xpath("//a/@href")
    print(a)
    

      

  • 相关阅读:
    nginx 启用http2 https 无法访问的问题
    Automating CSS Regression Testing
    jasmine 使用
    编写浏览器和Node.js通用的JavaScript模块
    Cucumber 使用例子
    Cucumber 之Gherkin
    Cucumber
    Cobertura 代码覆盖率测试
    spring && Cobertura && maven &&junit 单元测试以及测试覆盖率
    spring retry 使用
  • 原文地址:https://www.cnblogs.com/wwg945/p/10755457.html
Copyright © 2011-2022 走看看