如何用Wget或Python批量下载指定网站的.zip与.utu文件?
批量下载微软模拟飞行AI涂装文件的解决方案
我来帮你搞定批量下载这些AI涂装文件的问题!你的原始代码只做了最基础的链接提取,没处理Archive.org的链接结构、页面嵌套层级、超时重试和异常捕获这些关键问题,所以才会失败。下面分两部分给你提供更健壮的Python实现:
一、批量下载Project AI的.zip涂装文件
Project AI的文件需要经过分类页→子分类页→涂装详情页→下载链接的多层嵌套,我们需要逐层解析,同时处理Archive.org的链接重定向问题:
改进后的代码(Python 3.x)
import requests from bs4 import BeautifulSoup from urllib.parse import urljoin import os from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # 配置会话和重试机制,解决超时和连接问题 def create_session(): session = requests.Session() retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504] ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("http://", adapter) session.mount("https://", adapter) return session # 解析分类页面,获取子分类链接 def get_subcategory_links(session, base_url): sub_links = [] try: response = session.get(base_url, timeout=10) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") # 找到子分类的飞机图片链接(根据页面结构调整选择器) for link in soup.select("a[href*='acfiles.php?cat=']"): full_link = urljoin(base_url, link["href"]) if full_link not in sub_links: sub_links.append(full_link) return sub_links except Exception as e: print(f"获取子分类链接失败: {e}") return [] # 解析子分类页面,获取涂装详情页链接 def get_repaint_links(session, sub_url): repaint_links = [] try: response = session.get(sub_url, timeout=10) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") # 找到跳转到涂装详情页的链接(匹配repaints.php格式) for link in soup.select("a[href*='repaints.php?ac=']"): full_link = urljoin(sub_url, link["href"]) repaint_links.append(full_link) return repaint_links except Exception as e: print(f"获取涂装详情页链接失败: {e}") return [] # 解析涂装详情页,获取下载链接 def get_download_link(session, repaint_url): try: response = session.get(repaint_url, timeout=10) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") # 找到download.php的下载链接 download_link = soup.find("a", href=lambda x: x and "download.php?fileid=" in x) if download_link: return urljoin(repaint_url, download_link["href"]) return None except Exception as e: print(f"获取下载链接失败: {e}") return None # 下载文件到指定目录 def download_file(session, download_url, save_dir="project_ai_paints"): os.makedirs(save_dir, exist_ok=True) try: # 先获取文件名,从响应头或者链接解析 filename = download_url.split("fileid=")[-1] + ".zip" save_path = os.path.join(save_dir, filename) # 跳过已下载的文件 if os.path.exists(save_path): print(f"文件 {filename} 已存在,跳过下载") return response = session.get(download_url, timeout=15, stream=True) response.raise_for_status() with open(save_path, "wb") as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) print(f"成功下载: {filename}") except Exception as e: print(f"下载文件失败 {download_url}: {e}") # 主函数:批量处理两个分类页面 def main_project_ai(): session = create_session() base_urls = [ "http://web.archive.org/web/20050315112710/http://www.projectai.com:80/libraries/acfiles.php?cat=6", "http://web.archive.org/web/20050315112940/http://www.projectai.com:80/libraries/acfiles.php?cat=1" ] for base_url in base_urls: print(f"开始处理分类页面: {base_url}") sub_cats = get_subcategory_links(session, base_url) for sub_cat in sub_cats: print(f"处理子分类: {sub_cat}") repaint_pages = get_repaint_links(session, sub_cat) for repaint_page in repaint_pages: dl_link = get_download_link(session, repaint_page) if dl_link: download_file(session, dl_link) if __name__ == "__main__": # 先运行Project AI的下载 main_project_ai()
二、批量下载Flight 1 Ultimate Traffic的.utu文件
这个页面的下载链接是相对路径,我们只需要提取所有.utu格式的下载链接,直接批量下载即可:
对应的代码(可以追加到上面的脚本中)
def main_ultimate_traffic(): session = create_session() base_url = "http://web.archive.org/web/20060512161232/http://ultimatetraffic.flight1.net:80/utfiles.asp?mode=1&index=0" save_dir = "ultimate_traffic_paints" os.makedirs(save_dir, exist_ok=True) try: response = session.get(base_url, timeout=10) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") # 提取所有.utu的下载链接 for link in soup.select("a[href*='.utu']"): relative_link = link["href"] # 补全完整的Archive.org链接 full_download_link = urljoin(base_url, relative_link) # 解析文件名 filename = relative_link.split("id=")[-1] save_path = os.path.join(save_dir, filename) if os.path.exists(save_path): print(f"文件 {filename} 已存在,跳过") continue try: response = session.get(full_download_link, timeout=15, stream=True) response.raise_for_status() with open(save_path, "wb") as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) print(f"成功下载: {filename}") except Exception as e: print(f"下载失败 {full_download_link}: {e}") except Exception as e: print(f"获取Ultimate Traffic页面失败: {e}") # 调用Ultimate Traffic的下载函数 if __name__ == "__main__": # main_project_ai() # 取消注释可运行Project AI下载 main_ultimate_traffic()
关键改进点说明
- 会话与重试机制:用
requests.Session()保持连接,配合重试策略解决超时、5xx错误等问题 - 链接补全:用
urljoin处理相对链接,确保生成完整的Archive.org可访问链接 - 异常捕获:每个步骤都加了异常处理,避免单个链接失败导致整个程序崩溃
- 增量下载:检查文件是否已存在,跳过重复下载
- 流式下载:用
stream=True分块下载大文件,避免内存溢出
注意:运行代码前需要先安装依赖:
pip install requests beautifulsoup4 urllib3
内容的提问来源于stack exchange,提问作者Edward Winch
相关产品推荐
相关产品推荐

