zoukankan      html  css  js  c++  java
  • xpath学习记录

    <!DOCTYPE html> 
    <html> 
        <head> 
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>xpath test</title> 
        </head> 
        <body> 
            <div price="99.8"> 
                <div> 
                    <ul>
                     <li>时间</li> 
                     <li>地点</li> 
                     <li>任务</li> 
                    </ul> 
                </div> 
                <div id='testid' data-h="first">
                 <h2>这里是个小标题</h2>
                 <ol>
                     <li data="one">1</li> 
                     <li data="two">2</li> 
                     <li data="three">3</li> 
                     <li data="four">4</li> 
                 </ol>
                 <ol>
                     <li num="one">one1</li> 
                     <li num="two">two2</li> 
                     <li num="three">three3</li> 
                 </ol>
                 <ul>
                     <li code="84" id="testid">84</li> 
                     <li code="104">104</li> 
                     <li code="105">105</li> 
                     <li code="223">223</li> 
                 </ul>
                 <div> 
                     <ul> 
                         <li>11</li> 
                         <li>22</li>
                         <li>33</li> 
                         <li>44</li> 
                         <li>55</li> 
                         <li>66</li>
                         <li>77</li> 
                         <li>88</li> 
                         <li>99</li> 
                     </ul> 
                 </div>
                </div> 
                 <div id='testid'> 
                 <ol>
                     <li code="84">84</li> 
                     <li code="104">104</li> 
                     <li code="223">223</li> 
                 </ol>
                 <h3>这里是uu的内容 <a href="http://www.baidu.com">百度一下</a> 
                     <ul> 
                     <li>test1</li> 
                     <li>test2</li> 
                     </ul> 
                     <ul> 
                     <li>test3</li> 
                     <li>test4</li> 
                     </ul> 
                 </h3> 
                 </div> 
                 <div id="go"> 
                     <ul> 
                         <li>1</li> 
                         <li>2</li>
                         <li>3</li> 
                         <li>4</li> 
                         <li>5</li> 
                         <li>6</li>
                         <li>7</li> 
                         <li>8</li> 
                         <li>9</li> 
                         <li>10</li> 
                     </ul> 
                 </div> 
                 <div> 
                     <ul> 
                         <li>11</li> 
                         <li>22</li>
                         <li>33</li> 
                         <li>44</li> 
                         <li>55</li> 
                         <li>66</li>
                         <li>77</li> 
                         <li>88</li> 
                         <li>99</li> 
                     </ul> 
                 </div>
             </div> 
         </body> 
     </html>
    # !C:Python27 python
    # -*- coding: UTF-8 -*-
    from lxml import etree
    import sys
    import io
    import HTMLParser
    
    __author__ = 'Allen'
    fo = open('D:\pyapp/myPython/xpathTest/htmlForXpath.html', 'r')
    
    html = fo.read()
    # html_str = html.decode('utf-8').encode('GBK')
    html_str = html
    html_parser = etree.HTMLParser()
    tree = etree.parse(io.StringIO(html_str.decode('utf-8')), html_parser)
    # print tree.xpath('.//')
    print tree.xpath('//@code') 
    
    # type(tree.xpath('//div[@id="testid"]/h2/text() | //li[@data]/text()'))
    for item in tree.xpath('//div[@id="testid"]/h2/text() | //li[@data]/text()'):#多个匹配条件
        print item.encode('GBK')
    
    # 1. child:选取当前节点的所有子元素
    print tree.xpath('//div[@id="testid"]/child::ul/li/text()') #child子节点定位
    # print tree.xpath('//div[@id="testid"]/child::ol/text()')
    print tree.xpath('//div[@id="testid"]/child::ol/li[@data="two"]')  # [<Element li at 0x2665c08>]
    print tree.xpath('//div[@id="testid"]/child::*') #child::*当前节点的所有子元素
    #定位某节点下为ol的子节点下的所有节点
    print tree.xpath('//div[@id="testid"]/child::ol/child::*/text()') 
    print tree.xpath('//div[@id="testid"]/ol/child::*/text()')            # 上面两条语句的输出都是  ['1', '2', '3', 'one1', 'two2', 'three3']
    print tree.xpath('//div[@id="testid"]/child::*/child::*/text()') 
    
    # 2.attribute:选取当前节点的所有属性
    print tree.xpath('//div/attribute::id') #attribute定位id属性值
    print tree.xpath('//div[@id="testid"]/attribute::*') #定位当前节点的所有属性值
    
    # 3.ancestor:父辈元素 / ancestor-or-self:父辈元素及当前元素
    print tree.xpath('//div[@id="testid"]/ancestor::div/@price') #定位父辈div元素的price属性
    print tree.xpath('//div[@id="testid"]/ancestor::div/div[@id="good"]/@id') # ['good']
    print tree.xpath('//div[@id="testid"]/ancestor::div') #所有父辈div元素
    print tree.xpath('//div[@id="testid"]/ancestor-or-self::div') #所有父辈及当前节点div元素
    
    # 4.descendant:后代 / descendant-or-self:后代及当前节点本身,使用方法同上.
    
    # 5. following :选取文档中当前节点的结束标签之后的所有节点
    #定位testid之后不包含id属性的div标签下所有的li中第一个li的text属性
    print tree.xpath('//div[@id="testid"]/following::div[not(@id)]/.//li[1]/text()') 
    print tree.xpath('//div[@id="testid"]/following::div[not(@id)]/.//li/text()')           # 上面两行可以显示出 .// 的作用
    print tree.xpath('//div[@id="testid"]/following::div[not(@id)]/h3/ul/li[1]/text()') 
    print tree.xpath('//div[@id="testid"]/following::div[not(@id)]/.//li[1]') 
    # 6. namespace:选取当前节点的所有命名空间节点
    print tree.xpath('//div[@id="testid"]/namespace::*') #选取命名空间节点 ????
    
    # 7. 选取data值为one的父节点的子节点中最后一个节点的值
    print type(tree.xpath('//li[@data="one"]/parent::ol/li[last()]/text()')) 
    print tree.xpath('//li[@data="one"]/parent::ol/li[last()]/text()')
    print '==' 
    print tree.xpath('//li[@data="one"]/parent::ol/li') 
    # 8. preceding:选取文档中当前节点的开始标签之前的所有节点(需要同时有开始标签和结束标签才是一个完整的节点)
    print tree.xpath('//div[@id="testid"]/preceding::div/ul/li[1]/text()')[0]
    print tree.xpath('//div[@id="testid"]/preceding::head')
    print tree.xpath('//div[@id="testid"]/preceding::body') # 返回空列表[]
    print tree.xpath('//div[@id="testid"]/preceding::meta') # [<Element meta at 0x22c9c88>]
    print type(tree.xpath('//div[@id="testid"]/preceding::div/ul/li[1]/text()')[0])
    # 9. 下面这两条可以看到其顺序是靠近testid节点的优先
    print tree.xpath('//div[@id="testid"]/preceding::li[1]/text()')[0]  # 任务
    print tree.xpath('//div[@id="testid"]/preceding::li[3]/text()')[0]  # 时间
    
    # 10. 记住只能是同级节点
    print tree.xpath('//div[@id="testid"]/preceding-sibling::div/ul/li[2]/text()')[0] 
    print len(tree.xpath('//div[@id="testid"]/preceding-sibling::div/ul/li[2]/text()'))
    print tree.xpath('//div[@id="testid"]/preceding-sibling::li') #这里返回的就是空的了
    
    # 11. 选取带id属性值的div中包含data-h属性的标签的所有属性值
    print tree.xpath('//div[@id]/self::div[@data-h]/attribute::*') # ['testid', 'first']
    print tree.xpath('//div[@id]/self::div[@data-h]/attribute::data-h')
    
    # 12. 组合:定位id值为testid下的ol下的li属性值data为two的父元素ol的兄弟前节点h2的text值
    print tree.xpath('//*[@id="testid"]/ol/li[@data="two"]/parent::ol/preceding-sibling::h2/text()')[0]   # 这里是个小标题
    
    # 13. position 定位
    print tree.xpath('//*[@id="testid"]/ol/li[position()=2]/text()')[2]
    
    # 14. 定位所有h2标签中text值为`这里是个小标题`
    print tree.xpath(u'//h2[text()="这里是个小标题"]/text()')[0]   # 这里是个小标题
    
    # xpath中的相关函数
    # 15 统计
    print tree.xpath('count(//li[@data])') #节点统计
    
    # 16 concat:字符串连接
    print tree.xpath('concat(//li[@data="one"]/text(),//li[@data="three"]/text())')
    
    # 17 string只能解析匹配到的第一个节点下的值,也就是作用于list时只匹配第一个
    print tree.xpath('string(//li)')  # 时间
    
    # 18 解析节点名称,返回第一个匹配的名称
    print tree.xpath('local-name(//*[@id="testid"])') #local-name解析节点名称
    
    # 19 contains(string1,string2):如果 string1 包含 string2,则返回 true,否则返回 false
    print tree.xpath('//h3[contains(text(),"uu")]/a/text()')[0] 
    #使用字符内容来辅助定位 #百度一下 >
    #  组合
    #匹配带有href属性的a标签的先辈节点中的div,其前一个div节点下ul下li中text属性包含“务”字的节点的值 
    print tree.xpath(u'//a[@href]/ancestor::div/preceding::div/ul/li[contains(text(),"务")]/text()')[0]   #任务
    
    # 20 not:布尔值(否)
    print tree.xpath('count(//li[not(@data)])') #不包含data属性的li标签统计   18.0
    
    # 21 string-length:返回指定字符串的长度
    #string-length函数+local-name函数定位节点名长度小于2的元素
    print tree.xpath('//*[string-length(local-name())<2]/text()')[0] #百度一下
    
    #contains函数+local-name函数定位节点名包含di的元素 
    print tree.xpath('//div[@id="testid"]/following::div[contains(local-name(),"di")]') # [<Element div at 0x225e108>, <Element div at 0x225e0c8>]
    
    # 22 or:多条件匹配
    print tree.xpath('//li[@data="one" or @code="84"]/text()') #or匹配多个条件 ['1', '84']
    #也可使用|  ,注意or和|的用法有所不同
    print tree.xpath('//li[@data="one"]/text() | //li[@code="84"]/text()')   #|匹配多个条件 ['1', '84']
    
    # 23 position定位+last+div除法,选取中间两个 
    print tree.xpath('//div[@id="go"]/ul/li[position()=floor(last() div 2+0.5) or position()=ceiling(last() div 2+0.5)]/text()') #['5', '6']
    
    # 24 隔行定位:position+mod取余
    # position+取余运算隔行定位
    print tree.xpath('//div[@id="go"]/ul/li[position()=((position() mod 2)=0)]/text()') 
    
    # 25 starts-with:以。。开始
    # starts-with定位属性值code以8开头的li元素
    print tree.xpath('//li[starts-with(@code,"8")]/text()')[0]  # 84
    
    # 数值比较
    # 25 所有li的code属性小于200的节点
    print tree.xpath('//li[@code<200]/text()')   # ['84', '104', '105', '84', '104']
    
    # 25 div:对某两个节点的属性值做除法
    print tree.xpath('//div[@id="testid"]/ul/li[3]/@code div //div[@id="testid"]/ul/li[1]/@code')    # 2.65476190476
    print tree.xpath('89 div 9')
    
    # 组合:根据节点下的某一节点数量定位
    # 选取所有ul下li节点数大于5的ul节点
    print tree.xpath('//ul[count(li)>5]/li/text()')  # ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
    
    # 26 将对象还原为字符串
    s = tree.xpath('//*[@id="testid"]')[0]  #使用xpath定位一个节点  s <Element div at 0x2b6ffc8> 
    s2 = etree.tostring(s) #还原这个对象为html字符串 >>> s2
    print type(s2)
    print type(s2.decode('utf-8'))
    h = HTMLParser.HTMLParser()
    print h.unescape(s2)  #得到网页内容的html代码时,网页中的中文都会显示成 NCR 字符的形式,可使用HTMLParser的unescape()方法转换 https://www.jianshu.com/p/fb026309867b

    From:https://www.jianshu.com/p/1575db75670f

    几个的关键XPath概念:

    绝对vs相对XPath(/vs .

    • / 引入绝对位置路径,从文档的根开始。

    • . 从上下文节点开始引入相对位置路径。

    命名元素vs任何元素(enamevs *

    • /ename选择一个ename根元素

      • ./ename选择ename当前节点的所有子元素。

    • /* 选择根元素,无论名称如何。

      • ./*或者*选择上下文节点的所有子元素,而不管名称。

    后代或自我轴(//*

    • //ename选择ename文档中的所有元素。

      • .//ename选择ename上下文节点或其下的所有元素。

    • //* 选择文档中的所有元素,无论名称如何。

      • .//* 选择上下文节点处或下方的所有元素,无论名称如何。

  • 相关阅读:
    input type="number"
    Creating Directives that Communicate
    angular Creating a Directive that Adds Event Listeners
    angular 自定义指令 link
    cookie
    angular filter
    angular 倒计时
    angular $watch
    angular 自定义指令
    angular 依赖注入
  • 原文地址:https://www.cnblogs.com/Allen-win/p/9568346.html
Copyright © 2011-2022 走看看