← 返回 Skill 列表
extension
分类: 数据与分析无需 API Key

网站克隆

通用网站克隆技能。当用户提供一个网站 URL 并要求"克隆网站 / 离线保存网页 / 抓取页面和资源 / 镜像网页 / 下载整站静态副本"时使用。输入 URL,自动下载 HTML、CSS、JavaScript、图片、字体、音视频等全部静态资源,改写所有引用为相对路径,按镜像目录结构保存,并生成 report.md 下载报告。克隆结果可直接双击 index.html 离线浏览,布局样式尽量还原原站。适用于静态页面、文档站、博客、落地页、演示模板等场景。

person作者: user_243ed913hubcommunity

Website Clone - 通用网站克隆

Overview

将任意可公开访问的网页克隆为可离线浏览的静态副本:下载入口页面(可选同站子页面)及其引用的全部资源,把 HTML/CSS 中的引用统一改写为相对路径,输出结构清晰的目录树和下载报告。

核心脚本 scripts/clone_site.py 仅依赖 Python 3 标准库,无需安装任何第三方包。

Quick Start

python scripts/clone_site.py <url> -o <输出目录>

示例:

# 克隆单页
python scripts/clone_site.py https://example.com -o ./clone-example

# 克隆页面并跟进 1 层同站链接(最多 20 页)
python scripts/clone_site.py https://docs.example.com/guide -o ./clone-guide --depth 1 --max-pages 20

完成后用浏览器打开 <输出目录>/index.html 即可离线浏览。

懒加载 / JS 渲染站点(浏览器快照模式)

对滚动后才加载内容的站点(门户 feed、信息流、图片瀑布流等),纯 HTTP 抓取会丢失懒加载内容。此时先用快照脚本渲染出完整 DOM,再克隆:

# 1. 浏览器渲染 + 自动滚动触发懒加载(需 playwright,默认滚到页面高度连续 3 轮不变)
python scripts/snapshot.py <url> -o rendered.html

# 2. 从渲染后的 DOM 克隆(url 仍作为资源解析基准)
python scripts/clone_site.py <url> --html-file rendered.html -o <输出目录>

静态 DOM 模式(默认开启):从快照克隆时,脚本会剥离页面全部 <script> 并把 loading="lazy" 图片改为 eager——快照 DOM 已含全部懒加载内容,剥离 JS 后页面变成纯静态传统模式:滚动不会再触发运行时请求,也就不会出现"加载中转圈但永远出不来"的情况,且完全不需要联网。若确需保留原站 JS(如依赖脚本实现的交互),加 --keep-scripts,此时会注入离线优先 shim 拦截远程请求(注意:滚动加载类站点离线后仍会出现"加载中"提示)。

环境要求:pip install playwright && playwright install chromium。若已手动放置 Chromium(如 Chrome for Testing 解压到 %LOCALAPPDATA%\ms-playwright\chromium-<rev>\chrome-win64\),脚本会优先以 channel="chromium" 启动完整浏览器,无需 headless-shell。

判断何时用快照模式:克隆完成后若 index.html 中 <img> 数量明显偏少、或正文文本量远小于线上实际内容,即可判定存在懒加载,改用快照模式重新克隆。

输入参数

| 参数 | 默认值 | 说明 | |------|--------|------| | url(必填) | - | 目标页面 URL,可省略 https:// 前缀 | | -o, --output | ./site-clone | 输出目录 | | --depth N | 0 | 跟进同站 <a> 链接的层数,0 = 仅克隆入口页 | | --max-pages N | 30 | 最多下载的页面数 | | --max-assets N | 500 | 最多下载的资源数(防失控) | | --timeout S | 15 | 单请求超时秒数 | | --header "K: V" | 无 | 附加请求头,可重复(如 --header "Cookie: x=1" 传登录态) | | --no-referer | 关 | 默认自动携带 Referer: <入口页URL>(模拟浏览器,绕过防盗链);某些站点拒绝异常 Referer 时用此项关闭 | | --user-agent UA | Chrome UA | 自定义 User-Agent | | --html-file PATH | 无 | 用本地(浏览器渲染后)HTML 作为入口页,配合 snapshot.py 克隆懒加载站点 | | --keep-scripts | 关 | 从 --html-file 克隆时保留页面 JS 并注入离线 shim(默认剥离脚本、输出纯静态页) | | --no-offline-shim | - | 不注入离线优先拦截脚本 | | --no-static-render | - | 不提取内嵌 JSON / 不生成静态渲染回退页 |

输出目录约定:必须保存在用户当前工作空间内(例如 <workspace>/clones/<站点名>/),运行时显式传 -o;严禁使用系统临时目录。

输出结果

<输出目录>/
├── index.html              入口页(其余页面按原站路径镜像存放)
├── index.rendered.html     SPA 时的静态渲染回退页(无需 JS 即可看内容)
├── data/*.json             从页面提取的内嵌 JSON 数据
├── assets/<域名>/...       全部静态资源(CSS/JS/图片/字体/音视频)
└── report.md               下载报告:页面/资源清单、失败清单、功能开关状态

SPA 页面有三个打开方式:index.html(React 等运行时用内嵌数据渲染)→ 失败时用 index.rendered.html(纯静态卡片渲染,禁 JS 也能看)→ data/*.json(原始数据兜底)。

克隆完成后必须向用户报告:保存路径、页面/资源数量、失败项(见 report.md)。

工作流程

  1. 确认目标 URL 可公开访问(不是内网/登录墙页面;需要 Cookie 时用 --header 传入)。
  2. 选择合适的 --depth/--max-pages:单页演示用默认值;文档站/小型站按需提高。
  3. 运行脚本,检查控制台输出与 report.md。
  4. 抽查 index.html:确认资源引用为相对路径(assets/... 或 ../assets/...)。
  5. 将输出目录完整交付给用户,说明双击 index.html 即可离线浏览。

已妥善处理的常见情况

  • 相对路径改写:HTML 属性(src/href/srcset/poster/data-src 等)、<style> 块、内联 style、CSS 内 url() 与 @import 全部改写为相对路径;子目录页面自动计算正确的 ../ 层级;<base> 标签被识别并移除以防干扰。
  • 下载失败:失败资源的引用自动回退为原始绝对 URL(在线时可正常加载),并在 report.md 中逐条列出,页面不会出现死链。
  • 编码:自动检测 charset(HTTP 头 / meta 标签),GBK/GB2312 页面正确解码后统一以 UTF-8 写盘,并同步改写 meta charset,中文内容无损。
  • 扩展名修复:无扩展名 URL(如 CDN 图片接口)按 Content-Type + 文件魔数自动补全扩展名,保证 file:// 下浏览器能正确识别。
  • 懒加载属性:data-src / data-srcset / data-original / data-bg 等同样被抓取。
  • 边界安全:跳过 data:/javascript:/mailto:/锚点;同 URL 不同 query 生成不同文件名防覆盖;单文件 25MB 上限;跨域 CDN 资源可下载。

SPA 离线增强(内嵌数据提取与静态渲染)

对 React/Vue 等前端渲染站点,脚本内置三重离线保障(默认开启):

  1. 数据 URL 本地化:内嵌在 <script> 或 SSR 注释(如 <!--s-data:{...}-->)里的资源 URL 一并改写为本地路径,SPA 运行时渲染列表时图片走本地。
  2. 离线优先拦截:向每个页面 <head> 注入 shim,把 fetch/XHR 的远程请求模拟为网络失败——SPA 只能使用内嵌初始数据,绝不回退到在线数据(可用 --no-offline-shim 关闭)。
  3. 静态渲染回退页:提取内嵌 JSON,启发式识别其中的对象数组(卡片/列表数据),生成 rendered.html——标题/图片/链接/热值字段自动卡片化,图片映射本地资源,禁用 JS 也能完整浏览(可用 --no-static-render 关闭);原始 JSON 同步落盘 data/*.json 供复用。

已知边界:提取与渲染为通用启发式,复杂嵌套数据可能识别不全;SPA 若把初始数据完全放在独立 API(页面 HTML 无内嵌),则回退页无数据可渲染,此时 report.md 会注明"no embedded JSON list data found"。

适用范围与限制

适用:静态页面、文档站、博客、企业官网、落地页、HTML 模板/演示站,以及有内嵌初始数据的 SPA(React/Vue 服务端渲染站点,配合离线增强三件套)。

不适用 / 已知限制(遇到时应如实告知用户):

  • 数据完全依赖运行时 API 的 SPA:页面 HTML 不含内嵌数据时,只能克隆到布局框架;index.html 需联网才有内容(shim 注入后表现为空数据),静态回退页无数据可渲染。
  • 需要登录的页面:可用 --header "Cookie: ..." 传登录态,但会话过期后失效。
  • ES Module 相对导入的 JS:模块内部 import 语句不会改写,离线后可能加载失败。
  • 流媒体/加密视频(DRM)无法克隆。

合规提醒:本技能仅用于个人备份、学习研究、离线演示等合法用途。克隆结果受原网站版权约束,不得用于抄袭、仿冒或商用;请尊重目标站点 robots 协议,避免对同一站点高频抓取(脚本内置并发与数量上限即为此设计)。

Resources

  • scripts/clone_site.py - 核心克隆脚本(Python 3 标准库,零依赖),直接运行 python clone_site.py --help 查看参数。
  • scripts/snapshot.py - 浏览器快照脚本(需 playwright),用于懒加载/JS 渲染站点的 DOM 渲染与懒加载触发。