文件下载

一、文件下载说明

DrissionPage 提供了强大的文件下载管理功能。

能够主动发起下载任务,也能够对浏览器触发的下载任务进行管理。

1.1.download()方法

该方法可以主动发起下载任务,提供任务管理、多线程、大文件分块、自动重连、文件名冲突处理等功能。页面对象、标签页对象、<iframe>元素对象均支持此方法。

注意

  • 使用时,程序会自动同步调用方法的对象的 cookies 信息。

示例:

from DrissionPage import SessionPage

page = SessionPage()
# 下载QQ安装包
page.download("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe")

1.2.浏览器的下载任务

浏览器页面对象、标签页对象、<iframe>对象可对浏览器下载任务进行控制。包含以下功能:

  • 每个标签页对象可独立指定下载地址
  • 可在下载前指定重命名文件名
  • 可拦截下载任务,获取任务信息

示例:下载QQ安装包

from DrissionPage import ChromiumPage

page = ChromiumPage()
# 设置页面最大化
page.set.window.max()
# 打开网页
page.get('https://im.qq.com/pcqq/index.shtml')

# 点击一个会触发下载的链接,同时设置下载路径和文件名
mission = page('xpath://div[@id="introText"]/div[@class="btn-area"]/div[1]').click.to_download(r"D:\tmp", "QQ")
# 等待下载结束
mission.wait()

二、DownloadKit

DownloadKitDrissionPage 库中内置的一个功能强大的下载工具,专门用于处理文件下载任务。它支持多种页面对象(如 SessionPageChromiumPageWebPage 等),提供了多线程并发、大文件分块下载、自动重连、文件名冲突处理等功能。以下对象均支持

  • SessionPage
  • ChromiumPage
  • WebPage
  • ChromiumTab
  • MixTab
  • ChromiumFrame

2.1.添加任务

2.1.1.单线程任务

使用download()方法可添加单线程任务,该方法是阻塞式的,且只使用一个线程。

from DrissionPage import SessionPage

# 百度log图片
url = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
# 保存的地址
save_path = r"D:\tmp"

page = SessionPage()
# 下载文件
res = page.download(url, save_path)
print(res)

2.1.2.文件分块并行下载

使用download.add()方法的split参数可设置大文件是否分块下载。

使用download.set.block_size()方法可设置分块大小。

默认情况下载,超过 50M 的文件会自动分块下载。

from DrissionPage import SessionPage

page = SessionPage()
# 设置分块大小
page.download.set.block_size("30m")
# 默认分块下载
page.download.add("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe")
# 使用分块下载
page.download.add("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe", split=True)

2.1.3.阻塞式多线程任务

使用并行分块下载时,也可以使任务逐个下载,在add()后使用wait()即可。

from DrissionPage import SessionPage

page = SessionPage()
# 设置分块大小
page.download.set.block_size("30m")
# 默认分块下载
page.download.add("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe").wait()
# 使用分块下载
page.download.add("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe", split=True).wait()

2.2.任务管理

对象Mission用于管理下载任务,有以下功能:

  • 查看任务状态、信息、进度
  • 保存任务参数,如 url、连接参数等
  • 取消进行中的任务
  • 删除已下载的文件

2.2.1.获取单个任务对象

使用download.add()添加任务时,会返回一个任务对象。

from DrissionPage import SessionPage

page = SessionPage()
# 设置分块大小
page.download.set.block_size("30m")
# 使用分块下载
mission = page.download.add("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe", split=True)
print(mission.id)  # 获取任务id
print(mission.rate)  # 打印下载进度(百分比)
print(mission.state)  # 打印任务状态
print(mission.info)  # 打印任务信息
print(mission.result)  # 打印任务结果

除添加任务时获取对象,也可以使用download.get_mission()获取。在上一个示例中可以看到,任务对象有id属性,把任务的id传入此方法,会返回该任务对象。

m = page.download.get_mission(mission.id)
print(m)

2.2.2.获取全部任务对象

使用页面对象的download.missions属性,可以获取所有下载任务。该属性返回一个dict,保存了所有下载任务。以任务对象的id为 key。

from DrissionPage import SessionPage

page = SessionPage()

# 设置分块大小
page.download.set.block_size("30m")
# 默认分块下载
page.download.add("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe")
# 使用分块下载
page.download.add("https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240808_x64_01.exe", split=True)

# 获取全部任务对象
print(page.download.missions)

输出如下:

{1: <Mission 1 下载中 None>, 2: <Mission 2 下载中 None>}

2.2.3.载失败的任务

使用download.get_failed_missions()方法,可以获取下载失败的任务列表。

page.download_set.save_path(r'D:\download')
page.download('http://****/****1.pdf')
page.download('http://****/****1.pdf')
print(page.download.get_failed_missions()

输出

[
    <Mission 1 状态码:404 None>,
    <Mission 2 状态码:404 None>
    ...
]

完整案例:

from DrissionPage import SessionPage

# 初始化 SessionPage 对象
page = SessionPage()

# TODO 设置全局下载保存路径 这里的方法无法使用
# page.download_set.save_path(r'D:\download')

# 定义下载 URL 和保存路径
url1 = 'https://dldir1.qq.com/qqfile/qq/TIM3.4.8/TIM3.4.8.22092.exe'
url2 = 'https://dldir1.qq.com/qqfile/qq/PCQQ9.7.16/QQ9.7.16.29187.exe'

# 添加并发下载任务
mission1 = page.download.add(url1)
mission2 = page.download.add(url2)

# 打印下载进度和状态
print(f"Mission 1 Progress: {mission1.rate}%")
print(f"Mission 1 State: {mission1.state}")
print(f"Mission 2 Progress: {mission2.rate}%")
print(f"Mission 2 State: {mission2.state}")

# 获取所有下载任务的信息
missions = page.download.missions
for mission_id, mission in missions.items():
    print(f"Mission {mission_id}: {mission.info}")

# 获取下载失败的任务
failed_missions = page.download.get_failed_missions()
if failed_missions:
    print("Failed missions:")
    for mission in failed_missions:
        print(f"Mission ID: {mission.id}, Status Code: {mission.state}, Info: {mission.info}")
else:
    print("All downloads completed successfully.")

posted @ 2019-11-29 12:28  酒剑仙*  阅读(383)  评论(0)    收藏  举报