无服务器文件主页面访问权限时批量下载所有PDF文件的方案咨询
非统一规则命名PDF文件批量下载Python实现方案
核心实现思路
当前场景无法通过爬取列表页获取下载链接,因此采用「规则枚举->候选URL生成->有效性探测->批量下载」的逻辑实现,具体步骤如下:
- 梳理现有文件的命名规则:把已知的文件名前缀、后缀、编号规则全部枚举整理,例如示例中的
mmd+纯数字、jm+纯数字、dorot+数字+-+数字+可选e后缀,尽可能覆盖所有你能总结到的规律,减少有效文件的遗漏概率。 - 生成候选URL池:固定基础资源路径为
https://din-online.info/pdf/,根据梳理的规则设置合理的编号遍历范围(比如已知最大编号为38,可先设置遍历上限为100,后续再按需调整),拼接生成所有可能的完整PDF下载链接。 - 批量探测URL有效性:发送HEAD请求探测链接可用性,相比GET请求不需要下载文件内容,响应速度更快。仅当返回状态码为200时,判定该链接为有效可下载链接,加入待下载列表。请求时需添加正常浏览器的User-Agent请求头,避免被服务器拦截返回403。
- 优化下载逻辑:可添加多线程提升下载效率,同时增加本地文件校验逻辑,已下载完成的文件直接跳过,避免重复请求,还可支持断点续传应对网络波动导致的下载中断问题。
核心代码参考
首先安装依赖库:
pip install requests tqdm
示例代码:
import requests import time import os from tqdm import tqdm # 基础配置 BASE_URL = "https://din-online.info/pdf/" SAVE_DIR = "./pdf_downloads" HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } REQUEST_DELAY = 0.5 # 请求间隔,避免被封IP # 创建保存目录 os.makedirs(SAVE_DIR, exist_ok=True) def generate_candidate_urls(): """根据你总结的命名规则,修改这个函数生成候选URL""" candidates = [] # 规则1:mmd+数字,比如mmd1到mmd20 for num in range(1, 21): candidates.append(f"{BASE_URL}mmd{num}.pdf") # 规则2:jm+数字,比如jm1到jm50 for num in range(1, 51): candidates.append(f"{BASE_URL}jm{num}.pdf") # 规则3:dorot开头的文件,比如dorot25-1到dorot30-3,可选加e for main_num in range(20, 31): for sub_num in range(1, 4): candidates.append(f"{BASE_URL}dorot{main_num}-{sub_num}.pdf") candidates.append(f"{BASE_URL}dorot{main_num}-{sub_num}e.pdf") # 可补充更多你总结的规则 return list(set(candidates)) # 去重 def check_url_valid(url): """检查URL是否有效""" try: resp = requests.head(url, headers=HEADERS, timeout=10) time.sleep(REQUEST_DELAY) return resp.status_code == 200 except: time.sleep(REQUEST_DELAY) return False def download_file(url): """下载单个文件""" filename = url.split("/")[-1] save_path = os.path.join(SAVE_DIR, filename) # 已下载则跳过 if os.path.exists(save_path): print(f"{filename} 已存在,跳过下载") return try: resp = requests.get(url, headers=HEADERS, timeout=30, stream=True) total_size = int(resp.headers.get("content-length", 0)) with open(save_path, "wb") as f, tqdm( desc=filename, total=total_size, unit="B", unit_scale=True, unit_divisor=1024, ) as bar: for chunk in resp.iter_content(chunk_size=1024): if chunk: f.write(chunk) bar.update(len(chunk)) print(f"{filename} 下载完成") except Exception as e: print(f"{filename} 下载失败:{str(e)}") # 下载失败删除不完整的文件 if os.path.exists(save_path): os.remove(save_path) if __name__ == "__main__": print("正在生成候选URL...") candidate_urls = generate_candidate_urls() print(f"共生成{len(candidate_urls)}个候选URL,正在探测有效性...") valid_urls = [] for url in tqdm(candidate_urls): if check_url_valid(url): valid_urls.append(url) print(f"共找到{len(valid_urls)}个有效下载链接,开始下载...") for url in valid_urls: download_file(url) print("全部任务处理完成")
操作注意事项
- 合理调整请求间隔:根据服务器的响应情况调整
REQUEST_DELAY的数值,不要短时间发送大量请求,避免IP被封禁,也不要给对方服务器造成过大压力。 - 迭代更新命名规则:如果使用过程中发现了新的命名规则,直接补充到
generate_candidate_urls函数里即可,不用修改其他逻辑。 - 合规下载:确保你下载这些文件的行为符合该网站的用户协议和相关法律规定,避免违规操作带来的风险。
内容的提问来源于stack exchange,提问作者Menachem Minzberg
相关产品推荐
相关产品推荐

