Python(六十八)xpath案例实战

2022-02-27  本文已影响0人  Lonelyroots

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

上一篇下一篇

猜你喜欢

热点阅读