美文网首页
Python(六十八)xpath案例实战

Python(六十八)xpath案例实战

作者: Lonelyroots | 来源:发表于2022-02-27 22:54 被阅读0次

    07_xpath案例实战/01_xpath.py:

    """
    
        pip install lxml
        XPath常用规则:
            nodename        选取此节点的所有子节点
            /               从当前节点选区直接子节点
            //              从当前节点选取子孙节点
            .               选取当前节点
            ..              选取当前节点的父节点
            @               选取属性
    
        xpath中索引是从1开始的
    
    """
    from lxml import etree
    
    str1 = """
    <div>
        <ul>
            <li class="item-o"><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"><span class="bold">third item</span></a</li>
            <li class="item-1"><a href="link4. html">fourth item</a></li>
            <li class="item-o"><a class="test" href="link5.html">fifth item</a></li>
        </ul>
    </div>
    """
    tree = etree.HTML(str1)
    # print(tree)     # 打印<Element html at 0x1a5e1dfab48>
    # print(type(tree))       # 打印<class 'lxml.etree._Element'>
    # print(tree.xpath('//li'))       # 打印所有li标签对象,[<Element li at 0x1e050626e88>, <Element li at 0x1e050626dc8>, <Element li at 0x1e050626ec8>, <Element li at 0x1e050626f08>, <Element li at 0x1e050626f48>]
    # print(tree.xpath('//li/@class'))       # 打印所有li下的class属性值,['item-o', 'item-1', 'item-inactive', 'item-1', 'item-o']
    # print(tree.xpath('//li/a[@href="link1.html"]'))       # 打印li标签下a的href为"link1.html"的a标签对象[<Element a at 0x258ffa14e08>]
    # print(tree.xpath('//li//span'))     # 因为/是获取子元素,如果多层则使用//。打印[<Element span at 0x162dacd6848>]
    # print(tree.xpath('//li/a/@class'))     # 打印['test']
    # print(tree.xpath('//li/a//@class'))     # 打印a标签自己和之下的所有class属性值['bold', 'test']
    # print(tree.xpath('//li[last()]/a/@href'))     # 打印最后一个li的a的href值['link5.html']
    # print(tree.xpath('//li[last()-1]/a/@href'))     # 打印倒二个li的a的href值['link4.html']
    
    # print(tree.xpath('//li[1]/a/@href'))     # xpath中索引是从1开始的,打印第一个li的a的href值['link1.html']
    # print(tree.xpath('//li[1]/a/text()'))     # 提取第一个li里的a标签内容,打印['first item'],text()取出内容
    
    # result = tree.xpath('//li[1]/a')
    # print(result)       # 打印[<Element a at 0x2a215364988>]
    # print(result[0].text)       # 打印first item
    
    result = tree.xpath('//*[@class="bold"]')
    print(result[0].tag)       # 返回标签,打印span
    

    07_xpath案例实战/02_xpath.py:

    """
    
        xpath是一个非常好用的解析方法,同时也作为爬虫学习的基础。
        在后面的 selenium以及 scrapy框架中都会涉及到这部分知识,希望大家可以把它的语法掌握清楚,为后面的深入研究做好铺垫
    
        xpath高级
    
        /       子节点
        //      多层子节点
        @       选取某个属性
        []      选取条件
    
    """
    from lxml import etree
    
    parser = etree.HTMLParser(encoding='utf-8')
    tree = etree.parse('02_xpath.html',parser=parser)       # 如果碰到不规范的html文件时就会解析错误,自己创建html解析器,并增加parser参数
    print(tree.xpath('//@code'))        # 打印['84', '104', '223']
    
    """选取若干路径 | """
    # 这个符号用于在一个xpath中写成多个表达式,用|分开,每个表达式互不干扰。顺序是按照HTML里的顺序来的
    print(tree.xpath('//div[@id="testid"]/h2/text() | //li[@data]/text()'))     # 打印['这里是个小标题', '1', '2', '3']
    print(tree.xpath('//li[@data]/text() | //div[@id="testid"]/h2/text()'))     # 打印['这里是个小标题', '1', '2', '3']
    
    """child,选取当前节点的所有子元素"""
    # child:: 子节点定位
    print(tree.xpath('//div[@id="testid"]/child::ul/li/text()'))        # 打印['84内容', '104内容', '223内容']
    # child::* 当前节点的所有子元素
    print(tree.xpath('//div[@id="testid"]/child::*'))       # 打印[<Element h2 at 0x228afc98c88>, <Element ol at 0x228afc98cc8>, <Element ul at 0x228afc98d08>]
    # 定位当前节点下为ol的子节点下的所有节
    print(tree.xpath('//div[@id="testid"]/child::ol/child::*/text()'))      # 打印['1', '2', '3', '点我']
    
    """attribute选取当前节点的所有属性"""
    # attribute::id定位id属性值
    print(tree.xpath('//div/attribute::id'))        # attribute定位id属性值,打印['testid', 'go', 'Lonelyroots']
    print(tree.xpath('//div/@id'))        # 打印['testid', 'go', 'Lonelyroots']
    # attribute::*定位当前节点的所有属性
    print(tree.xpath('//div[@id="testid"]/attribute::*'))       # 打印['testid', 'first']
    
    """ancestor:父辈元素 / ancestor-or-self:父辈元素及当前元素"""
    # 定位父辈div元素的price属性
    print(tree.xpath('//div[@id="testid"]/ancestor::div/@price'))       # 打印['99.8']
    # 所有父辈div元素
    print(tree.xpath('//div[@id="testid"]/ancestor::div'))      # 打印[<Element div at 0x1ae7fd95ec8>]
    # 所有父类及当前节点div元素
    print(tree.xpath('//div[@id="testid"]/ancestor-or-self::div'))      # 打印[<Element div at 0x280c7e28188>, <Element div at 0x280d7555ec8>]
    
    """following:选取文档中当前节点的结束标签【之后】的所有节点"""
    # 定位testid之后不包含id属性的div标签下所有的li中第一个li的text属性
    print(tree.xpath('//div[@id="testid"]/following::div[not(@id)]//li[1]/text()'))     # 打印['test1']
    print(tree.xpath('//div[@id="testid"]/following::div[@id="go"]//li[1]/text()'))     # 打印['1']
    
    """preceding:选取文档中当前节点的开始标签【之前】的所有节点"""
    # 记住是标签开始之前,同级前节点及其子节点
    print(tree.xpath('//div[@id="testid"]/preceding::div/ul/li[1]/text()'))     # 打印['时间']
    
    """parent:选取当前节点的父节点"""
    # 选取data值为one的父节点的子节点中最后一个节点的值
    print(tree.xpath('//li[@data="one"]/parent::ol/li[last()]/text()'))     # 打印['3']
    
    
    """函数"""
    """count:统计"""
    # 节点统计
    print(tree.xpath('count(//li[@data])'))     # 统计节点,打印3.0
    
    """concat:字符串连接"""
    print(tree.xpath('concat(//li[@data="one"]/text(),//li[@data="three"]/text())'))     # 打印 13
    print(tree.xpath('concat(//li[@code="84"]/text(),//li[@code="223"]/text())'))     # 打印 84内容223内容
    
    """contains(string1,string2):如果string1包含string2,则返回true,否则返回false"""
    print(tree.xpath('//h3[contains(text(),"h3")]/a/text()'))       # 打印['百度一下']
    print(tree.xpath('//div[@id="go"]//li[contains(@class,"it1")]/text()'))     # 打印['1', '5', '6']
    
    """not 布尔值(否)"""
    print(tree.xpath('count(//li[not(@data)])'))        # 打印 18.0
    

    07_xpath案例实战/03_wallhaven提取.py:

    """
    
        官网地址:
            https://wallhaven.cc/latest
    
        1. 请求当前页数  请求1
        2. 拿出图片的ID
        3. 拼接下载链接
        4. 下载         请求2
    
        jpg/png
    
        【1】一边爬一边下
        【2】先准备下载链接,再下载
    
        a链接:href="https://wallhaven.cc/w/l3veoy"
        缩略图img链接:https://th.wallhaven.cc/small/l3/l3veoy.jpg
        下载的详细链接:https://w.wallhaven.cc/full/l3/wallhaven-l3veoy.png
    
    """
    from requests_html import HTMLSession
    import re
    
    session = HTMLSession()
    
    url = "https://wallhaven.cc/latest?page="
    proxie = {
        'http':'113.237.244.115:9999'
    }
    ImgUrlList = []
    for page in range(1,2):
        response = session.get(url=url+str(page),proxies=proxie)
        imgUrl = response.html.xpath('//a[@class="preview"]/@href')
        # 返回链接:如['https://wallhaven.cc/w/e7pdqr', 'https://wallhaven.cc/w/pkvrpm']
        for url in imgUrl:
            ImgUrlList.append(url)
    print(ImgUrlList)
    
    for imgUrl in ImgUrlList:
        id = imgUrl[-6:]
        suffix = 'jpg'
        url = f"https://w.wallhaven.cc/full/{id[:2]}/wallhaven-{id}.{suffix}"
        response = session.get(url=url)
        if response.status_code != 200:
            suffix = 'png'
            url = f"https://w.wallhaven.cc/full/{id[:2]}/wallhaven-{id}.{suffix}"
            response = session.get(url=url)
        with open('images/{}.{}'.format(id,suffix),'wb') as fp:
            fp.write(response.content)
            print(f'============{id}下载完成============')
    

    07_xpath案例实战/04_百度热搜.py:

    from requests_html import HTMLSession
    
    session = HTMLSession()
    
    url = "https://top.baidu.com/board?tab=realtime"
    response = session.get(url=url)
    response.encoding = response.apparent_encoding
    print(response.html.xpath('//div[@class="c-single-text-ellipsis"]/text()'))
    

    文章到这里就结束了!希望大家能多多支持Python(系列)!六个月带大家学会Python,私聊我,可以问关于本文章的问题!以后每天都会发布新的文章,喜欢的点点关注!一个陪伴你学习Python的新青年!不管多忙都会更新下去,一起加油!

    Editor:Lonelyroots

    相关文章

      网友评论

          本文标题:Python(六十八)xpath案例实战

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