Python批量抓取网页存成本地HTML:离线镜像与归档
讲解用requests批量抓取多个网页完整HTML保存到本地,自动建目录、按URL生成文件名,方便离线归档、备份网页内容、做本地镜像。
场景痛点
工作中遇到重要网页想留档:规章制度页面、合同模板、项目文档、新闻公告,怕以后网站改版或者删掉就找不到了。手动一个个"另存为"太费时间,用脚本把URL列表批量存成HTML文件,连带着目录结构一起归档,随时能离线打开。
用到的库
pip install requests beautifulsoup4 lxml
完整代码
# 导入库
import os
import re
import time
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
HEADERS = {
"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36"),
}
def url_to_filename(url):
"""把URL转成合法的文件名"""
# 去掉协议
name = re.sub(r"^https?://", "", url)
# 把非法字符都换成短横线
name = re.sub(r"[^\w\-]", "-", name)
# 压缩连续短横线,限制长度
name = re.sub(r"-+", "-", name).strip("-")
return name[:100] + ".html"
def save_one(url, base_dir="web_archive"):
"""抓取单个网页并保存为本地HTML"""
try:
resp = requests.get(url, headers=HEADERS, timeout=15)
resp.encoding = resp.apparent_encoding
# 文件已经存在就跳过
filename = url_to_filename(url)
save_path = os.path.join(base_dir, filename)
if os.path.exists(save_path) and os.path.getsize(save_path) > 0:
return ("skip", url, filename)
os.makedirs(base_dir, exist_ok=True)
with open(save_path, "w", encoding="utf-8") as f:
f.write(resp.text)
return ("ok", url, filename)
except Exception as e:
return ("fail", url, str(e))
def batch_save(urls):
"""批量抓取,5个线程并发"""
os.makedirs("web_archive", exist_ok=True)
results = []
with ThreadPoolExecutor(max_workers=5) as pool:
futures = {pool.submit(save_one, u): u for u in urls}
for fut in as_completed(futures):
status, url, info = fut.result()
results.append((status, url, info))
print(f"[{status}] {url[:60]}")
# 写一个索引文件
with open("web_archive/_index.txt", "w", encoding="utf-8") as f:
for status, url, info in results:
f.write(f"{status}\t{url}\t{info}\n")
return results
if __name__ == "__main__":
# 要归档的URL列表
urls = [
"https://example.com",
"https://www.python.org/about/",
"https://docs.python.org/3/tutorial/",
"https://pypi.org/",
]
batch_save(urls)
print("完成,文件保存在 web_archive/ 目录")
代码讲解
url_to_filename把URL转成合法文件名:去掉http://,把/、?、=等非法字符都换成-,再压缩连续短横线,限制长度避免路径过长。save_one抓单个网页并写入本地HTML文件,用w文本模式加utf-8编码,中文不会乱码。- 文件已存在且非空就跳过,脚本中断后再跑能续传。
- 线程池5个并发,比串行快几倍,抓几十个页面也就十几秒。
- 最后写一个
_index.txt索引文件,记录每个URL对应保存成哪个文件、成功还是失败,方便事后核对。
运行结果
运行后控制台逐行打印每个URL的状态(ok/skip/fail),当前目录生成 web_archive/ 文件夹,里面是一堆以URL命名的HTML文件和一个索引文件。双击任意HTML文件用浏览器打开,能看到离线版本的网页。
注意事项
- 保存的HTML只是页面源码,里面的图片、CSS、JS还是外链的,离线打开会丢样式。要完整镜像需要额外下载资源并改写路径。
- 文件名不要太长,Windows路径长度有260字符限制,所以截断到100字符。
- 批量归档前先和网站方确认是否允许保存,个人学习备份没问题,大规模镜像别人站点要慎重。
- 抓取间隔适当加一点
time.sleep(0.5),礼貌访问。

更新时间:2026-09-14 20:52:04
上一篇:Python批量抓取网页标题列表:并发请求与结果汇总