通过python脚本下载网盘中的文件

需求

最近在写一些python的代码,因为经常用到光谱插值,所以想把相关的函数连同用到的光谱模板包装成一个python包,方便调用。这样方便自己在不同的电脑上安装,可能也能方便其他一些同学使用。

代码还好说,上传到GitHub或者别的代码托管网站上即可。但是数据文件(光谱的格点文件)比较大,国内因为众所周知的原因,这么大的数据文件想直接从GitHub上download下来,不挂VPN的话,实在不容易。所以我就想把数据文件存储在国内的网盘上,程序包在运行的时候如果需要用到哪个数据文件,可以自动从网盘上下载下来。

碰到的问题

我把文件上传到网盘之后发现,国内的这些网盘为了防止脚本自动下载,没有提供可以直接下载文件的URL。即使我生成了分享链接,通过浏览器打开分享链接,其中并没有可以直接对应数据文件的link,因此也没办法通过requests之类的包得到对应的文件下载链接。共享链接对应的页面上,那个Download按钮里边并没有对应数据的超链接,而是在鼠标点击按钮的时候会执行一个JS脚本,由这个JS脚本来完成下载。这样就把典型的自动通过URL来下载文件的路堵死了。

解决办法

这时候能想到的下载文件的方式是,通过某些python包,像一个正常的浏览器那样加载分享链接对应的页面,然后脚本自动完成对其中的Download按钮的点击动作,然后自动完成下载。在网上搜索一番,发现还真有这样的工具。具体原理就是真的通过一些常见的浏览器(Chrome,FireFox,Edge,Safari)加载网页,然后通过指令完成自动点击,填充等动作。这样的包完全契合了我的需求。

下边以其中一个这类包 selenium为例,展示代码具体要怎么实现。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os
import time

# 设置Chrome浏览器下载文件的默认目录(在主目录下的指定文件夹)
download_dir = os.path.expanduser("~")

# 配置Chrome选项
chrome_options = Options()
chrome_options.add_argument("--headless")  # 无头模式,不显示浏览器窗口
chrome_options.add_argument("--disable-popup-blocking")  # 禁用弹出窗口阻止
chrome_options.add_argument("--disable-notifications")  # 禁用通知
chrome_options.add_argument("--disable-gpu")  # 禁用GPU加速

# 设置下载文件的相关配置
prefs = {
    "download.default_directory": download_dir,
    "download.prompt_for_download": False,
    "download.directory_upgrade": True,
    "safebrowsing.enabled": False,
}

chrome_options.add_experimental_option("prefs", prefs)

# 创建Chrome浏览器实例
driver = webdriver.Chrome(options=chrome_options)

# 打开一个网页,触发文件下载操作
url = 'https://www.jianguoyun.com/p/DZmcNoUQ2ZfcCBjW-5cFIAA'

driver.get(url)

# 点击下载链接
try:
    driver.find_element('partial link text', 'Download').click()
except:
    driver.find_element('partial link text', '下载').click()

# 等待一段时间,留足够的时间给文件下载
t0 = time.time()
while time.time() - t0 < 60:
    time.sleep(5)  # 这里可以根据实际情况调整等待时间
    print('.', end="", flush=True)
    # 检查下载目录中是否有预期的文件
    expected_file_name = "MARCS_grid.hdf5"  # 你期望的文件名
    downloaded_files = os.listdir(download_dir)
    file_downloaded = expected_file_name in downloaded_files

    # 如果文件已经下载,则退出循环
    if file_downloaded:
        print(f"File {expected_file_name} downloaded successfully.")
        break

# 如果文件没有下载,则抛出异常
if not file_downloaded:
    print(f"File {expected_file_name} not found in download directory.")

# 关闭浏览器实例
driver.quit()

上述的代码可以完成从坚果云上下载共享文件的任务,前提是对应的文件权限要设置成任何人可以下载。

其他类似的工具还有Helium, Playwright等。

Visits: 404

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

*