320k个PDF文件批量获取与存储的优化方案咨询
一、现有Colab+NextCloud方案的优化点
1. 控制并发请求,避免限流与资源耗尽
串行下载效率极低,且易触发目标服务器速率限制。改用异步/多线程下载,通过信号量控制并发数(建议10-20之间),避免同时发起过多请求导致封禁或Colab资源过载。搭配重试机制,处理网络波动导致的下载失败。
示例异步下载代码(aiohttp+tenacity):
import aiohttp import asyncio from tenacity import retry, stop_after_attempt, wait_exponential import os import json # 加载PDF链接(根据你的JSON结构调整) with open("links.json", "r") as f: links = [item["url"] for item in json.load(f)] # NextCloud挂载目录 NC_TARGET = "/content/nextcloud/pdf-storage/" os.makedirs(NC_TARGET, exist_ok=True) # 跳过已下载文件 downloaded = set(os.listdir(NC_TARGET)) @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)) async def fetch_pdf(session, url, save_path): async with session.get(url) as resp: resp.raise_for_status() with open(save_path, "wb") as f: async for chunk in resp.content.iter_chunked(1024*1024): f.write(chunk) async def main(): # 限制并发数 semaphore = asyncio.Semaphore(15) async with aiohttp.ClientSession() as session: tasks = [] for url in links: filename = url.split("/")[-1] save_path = os.path.join(NC_TARGET, filename) if filename in downloaded: continue # 信号量控制并发 async with semaphore: tasks.append(asyncio.create_task(fetch_pdf(session, url, save_path))) await asyncio.gather(*tasks) if __name__ == "__main__": asyncio.run(main())
2. 先本地缓存,再批量同步至NextCloud
直接逐个写入NextCloud会频繁触发网络IO,拖慢速度。改为先下载到Colab临时本地磁盘(/content/,读写速度远快于网络),积累到一定数量(如1000个)后,再批量同步到NextCloud。若单批次文件总大小超过Colab临时磁盘容量(约100GB),则拆分更小批次处理。
3. 优化NextCloud挂载方式
替换原生WebDAV挂载为rclone,它支持缓存、断点续传和批量同步,稳定性与性能远优于普通WebDAV。在Colab中配置rclone连接NextCloud后,可通过命令行快速同步:
# 安装rclone !curl https://rclone.org/install.sh | sudo bash # 配置NextCloud远程(按提示输入地址、用户名、密码) !rclone config create nextcloud_webdav webdav url=https://your-nextcloud-domain/remote.php/dav/files/your-username/ vendor nextcloud # 批量同步本地文件到NextCloud !rclone sync /content/downloaded-pdfs/ nextcloud_webdav:target-folder/
4. 防止Colab会话超时
Colab Pro+会话虽长,但长时间无输出仍可能被回收。在代码中加入定期日志输出(如每下载1000个文件打印进度),同时将已下载文件名列表保存到NextCloud或Google Drive,会话中断后可从断点继续下载,无需从头开始。
二、替代高效方案
1. 用rclone直接批量下载+同步
rclone原生支持HTTP链接批量下载,无需编写Python脚本。将JSON中的链接导出为文本文件(每行一个链接,命名为links.txt),然后执行:
# 批量下载所有链接到本地 !rclone copyurl --batch-size 100 --links links.txt /content/temp-pdfs/ # 同步到NextCloud !rclone sync /content/temp-pdfs/ nextcloud_webdav:pdf-collection/
rclone会自动处理重试、断点续传和并发控制,性能比自定义脚本更稳定。
2. 借助Google Cloud Storage(GCS)中转
若PDF总容量较大,可先将文件下载到GCS(Colab与GCS同区域时速度极快),再通过rclone或NextCloud外部存储功能将GCS挂载到NextCloud实现同步。这种方式能避免Colab临时磁盘容量限制,且GCS的下载/存储性能更可靠。
3. 分布式并行下载
将320k个链接拆分为多个批次(如每批次10k个),同时开启多个Colab Pro+会话分别处理不同批次,最后将各批次文件合并到NextCloud同一目录。这种方式能最大化利用Colab并行资源,大幅缩短总下载时间。
内容的提问来源于stack exchange,提问作者Mads Fristed Navne

