
1. 先搞清楚“网站逆向重建”到底在做什么1.1 三种典型需求决定三种“克隆”路线先聊聊这个项目到底解决什么问题。网站逆向重建说白了就是你把一个已经存在的网站从头到尾“重新造一遍”。接到这类活儿的场景通常有三种第一种是公司内部的老系统要改技术栈比如十年前用jQuery写的东西现在要迁到React但业务逻辑和页面长相不能动客户只认“一模一样”第二种是竞品网站的页面布局、交互细节你看着不错想在自家产品里做一套类似的但不可能直接扒代码第三种是客户手里只有线上地址源文件早就丢了重构只能以线上版本为准。这三种需求对应的处理路线完全不一样。第三种最依赖逆向能力因为你手上只有一个“黑盒”要从运行时反推实现方案第一种最考验组件化拆分能力因为业务逻辑藏在无数DOM节点里第二种最容易走歪很多人做着做着就变成了像素级抄袭这里必须先提醒一句逆向重建只能用于自己有权重做的网站、学习研究和功能借鉴别人的原创设计、文案、品牌资产依然受法律保护这条线不要越。把目标网站拿来做技术研究没问题但上线商用必须拿到授权。1.2 技术边界哪些能复制哪些必须付钱网站逆向重建常见的技术手段我盘了一圈大概分三类静态采集、交互录制、视觉识别。静态采集最简单拿到页面的HTML、CSS、JS直接解析交互录制进阶一点用Playwright这类工具把页面上的点击、滚动、悬浮行为录下来分析交互逻辑视觉识别是现在AI最擅长的地方给模型一张网页截图它能直接给你描述出布局结构和视觉规范。但这里头有两条线是碰不得的。一条是“网站本身的授权”robots.txt里明确禁止采集的路径就别硬碰了另一条是“第三方资产”页面里的字体图标、图片、动态数据如果属于原作者或第三方版权逆向的时候你会发现根本拷不干净——字体文件被编码混淆过、图片做了防盗链、接口返回的是加密数据。正规做法是把页面当作“视觉和结构参考”代码用自己的技术栈重写、图片用占位符替代、数据用Mock兜底这才是ai-website-cloner-template这套模板贯穿始终的设计底线。刚才说的三条路线和边界问题也是我决定做“模板”而不是“一次性脚本”的直接原因——只有把最优流程固化下来每次开工才能在同样的坑位上不栽第二次。2. ai-website-cloner-template的整体设计一条可复制的流水线长什么样2.1 为什么“模板”比“单次脚本”更有价值很多人第一反应是逆向重建网站直接写个爬虫脚本不就完事了吗还真不是。单次脚本是一次性的这次跑通了下次换一个目标网站大概率要推倒重来。因为每个网站的DOM结构、加载方式、交互复杂度都不一样脚本里但凡有一步是“硬编码”的换站点就失灵。而模板的本质是“流程的标准化”它把一次成功案例里沉淀下来的所有合理决策、参数配置、踩坑规避方案都固化成了可复用的模块。我最初做ai-website-cloner-template也是从单次脚本起步的第一版确实能跑但到了第二个目标站点就翻车了——那个站是无限滚动加载的我的脚本只采集了首屏后面所有内容全部丢失。后来我把采集环节拆成“页面类型判断”加“滚动策略配置”把页面分成引导页、列表页、详情页、后台页四类每类有不同的采集深度同一套代码在不同站点上都能工作这才有资格叫“模板”。2.2 五大核心模块与选型依据一个真正的可复制流水线应该像一条PLC控制的产线每个工位只负责一件确定的事。我的模板分成了五个核心模块站点侦察模块负责入场摸底。这个模块要做的是拿到目标站点后先判定它的技术栈是服务端渲染还是纯前端SPA用了什么框架再抓取robots.txt和sitemap.xml生成一个目标页面清单。这里选型的逻辑是先看是“静态HTML直出”还是“JS动态渲染”决定了后面用requests还是Playwright。如果是SPArequests拿到的HTML基本是空壳不改采集引擎必死无疑。页面采集模块负责快照。这一层我用Playwright做主力因为它能执行JavaScript能模拟真实浏览器行为对现代网站友好得很。采集时不是单纯保存HTML而是“三件套”一起抓渲染后的HTML、整页截图、每个元素相对视口的坐标数据。截图给AI做视觉参考DOM给AI做结构参考坐标数据留给后面的校验环节做像素级对齐缺一样都不行。结构提取模块负责把DOM“洗”成AI能理解的东西。这一步我个人认为是整套模板的灵魂后面单独展开说。代码生成模块负责调大模型生成代码。选型上没有太多悬念Claude和GPT在这一代模型里对前端代码的理解能力都很强关键在于Prompt的组织方式。模板里所有Prompt都是“系统指令加少量示例加目标数据”三段式结构示例会带3到5个上一步生成的结构片段让模型照着这个规格继续写而不是自由发挥。校验反馈模块负责让机器先兜底人工再做最终判断。这个模块会做三件事像素对比检测整页相似度、可交互点覆盖率计算、资源加载错误扫描。三个指标都过了才轮到人去看。2.3 Prompt工程“AI读站”才是整个流水线的真正重心这一节必须好好讲讲结构提取和Prompt的配合因为这是整条流水线里最依赖经验的部分。我先说结论直接把手抓的HTML喂给AI让它“看着办”效果极差。原因很简单线上HTML里充满了压缩后的类名、内联脚本、嵌套十几层的div、没用的追踪代码模型会把注意力浪费在噪音上。模板里的做法是先用脚本对DOM做归一化处理把类名重写成语义化标签、把事件监听器提取出来标注在节点上、把文本密度过低的容器折叠掉最后输出一份精简但结构完整的AST描述。Prompt这边对应的调教方法是不给模型整个页面只给一个“组件级别”的结构片段。比如一个导航栏系统指令要求模型只关注这个组件然后sample数据给三个不同风格导航栏的“结构描述对预期代码”示例。这样模型产出的每个组件代码都是独立、可复用、风格可控的。每个组件生成完了再单独跑一遍语法校验和依赖检查有错当场重生成省得最后组装时满屏红叉。这里有一个很关键的参数生成温度。我实测下来组件代码生成温度调到0.2是最稳的太低了代码千篇一律太高了模型容易自己发挥。整站骨架生成可以到0.4因为需要一点结构上的灵活性。3. 实操5步跑通网站逆向重建流水线3.1 站点侦察与目标页面清单整个流水线的起点其实不是写代码而是做一张“页面地图”。我会先用Wappalyzer这类工具看一眼目标站点用的什么技术栈再拉一下sitemap.xml看看站点有哪些页面。如果是JS渲染的SPAsitemap往往不完整这时候需要手动点几下摸清路由结构把关键页面类型和对应URL记下来填进模板的target.json里。我自己的习惯是把页面分成四类每类的采集策略不一样。引导页和列表页只需要采首屏加滚动两屏留足上下文就行详情页要完整采因为内容结构复杂组件拆分时不能缺胳膊少腿后台页面通常登录后才能看模板里专门留了一个“已登录状态导入”的口子你可以把自己的Cookie写进采集配置里。同时robots.txt里被Disallow的路径模板默认会自动跳过这个逻辑一是合规考虑二是那些路径通常是后台和敏感接口采了也没价值。3.2 批量采集页面快照侦察结束进入真正动手的环节。模板里采集模块的核心逻辑是循环读取target.json对每个URL做四件事打开页面、等待网络空闲、滚动触发懒加载、保存“三件套”快照。这里有个坑必须说等网络空闲的判断不能死等有些页面会有轮询请求一直不断等了也白等。模板里设了“网络空闲2秒或超时10秒”的双条件谁先到算谁这才不会卡死。截图这块模板默认会保存两种规格整页长图和视口截图。整页长图给AI看全貌视口截图给校验环节做像素对比用。另外还有一个容易被忽略的设置等待字体加载完成。网页里有很多用WebFont的站点加载前和加载后的排版完全不一样字体没就位就截图等于拿一张残废图给AI参考生成出来的间距必然对不上。3.3 DOM归一化与可交互点标注现在到了灵魂环节。采集回来的HTML原始文件动辄几百KB直接扔给大模型就是灾难。模板的DOM归一化脚本会做以下这些事先删掉所有script标签、style标签、meta标签、noscript块这些对结构理解没有帮助然后把class名从压缩后的一串字符映射成语义化标识映射规则是一张可配置的词典再压缩嵌套层级把无意义的包壳标签比如多余的div、span折叠掉同时保留有布局意义的父容器和兄弟结构最后把所有文本节点提取出来和对应的保底语义描述一起存放在一个单独的文本块中。这里的核心逻辑是AI需要看到的是“信息架构”而不是代码实现。就像给人看建筑图你给测绘原始点云没有用应该画成平面图。可交互点标注是紧接着的结构提取动作脚本会把带href的链接、带click监听器的元素、input、select、button全部提取出来标注它们的类型、位置、默认行为。这份“交互清单”后续有两个用途给AI生成代码时让它保证这些交互都存在给校验模块计算“交互覆盖率”。这就保证了生成出来的东西不是只有一张皮而是真能点、能跳、能提交的。3.4 AI生成组件级代码归一化完成之后模板会按预设粒度把页面切成多个组件区块。切分的粒度是根据页面布局自动定的默认按header、footer、main内的横向区块切分。切分的逻辑很简单识别DOM里的同级兄弟节点把连续的同类型节点归成一个列表组件单独的大块区域各归各的这样最后生成的代码是组件树结构而不是一个5000行的巨型文件。每个组件进入生成流程时会拿到三样东西结构描述、截图切片、设计偏好。结构描述就是归一化后的AST片段截图切片是按组件外框坐标裁剪出来的图设计偏好来自模板的全局配置比如“保留圆角风格、主色调改用品牌色”这类约束。生成出来的代码是标准的函数组件带props接口样式用CSS Modules方便后续独立调试。Prompt的组织方式我贴一个简化版的系统指令实际使用里模板会按组件类型替换不同的示例你是一名资深前端工程师任务是根据给定的网页组件结构和截图生成符合现代工程规范的前端代码。 硬性要求 1. 仅输出代码不要输出任何解释 2. 代码使用React函数组件编写样式使用CSS Modules 3. 组件外观必须与截图一致间距和字体大小按截图实测估计 4. 所有可交互元素必须有对应的事件处理和aria标签 5. 使用到的图片资源统一使用占位地址后缀保持与原图一致 6. 数据展示类内容一律使用props传入不得硬编码 下面是三个参考示例 [示例一][示例二][示例三] 下面是要生成的目标组件 [结构描述] [截图说明]3.5 组装、校验与人工走查组件生成完之后模板会调用组装脚本把所有组件拼成一个页面。这里有个很容易炸的环节样式冲突。每个组件的CSS Modules理论上互不干扰但全局样式比如reset、字体、色变量还是会打架。所以模板在组装时会把所有页面的公共样式抽到一个global层然后走一遍构建流程构建报错就回到生成环节自动修复。校验模块的指标很直白。像素相似度取原始截图和生成页面的截图做diff相似度低于95%的区块标红处理交互覆盖率统计原始页面可交互点和生成页面可交互点的匹配程度低于90%判定不通过需要回到生成环节补充资源正确性扫描则检查所有图片、字体、接口地址是否都替换成了合法资源。三道校验都过了才轮到人来做视觉和体验走查。我实际用下来这套机器校验加人工走查的配合通常能砍掉一大半返工时间。机器能发现的不需要人一遍遍盯人的精力只花在“感觉不对但指标正常”的微妙问题上。4. 我在踩坑中总结的10条实操铁律回头看了一整轮网站逆向重建项目的开发过程踩得最深的那十几层坑基本可以收敛成10条经验每条都是真金白银换来的。第1条先确认目标站点的技术栈再选采集器。静态站用requests都能处理但SPA必须上浏览器级采集工具早起贪图轻量用requests结果拿回来全是空壳DivAI照着生成了一个有结构没内容的页面浪费了一整天。采集器选型做对了后面省的是几倍的时间。第2条采集时一定要保留“原页面截图”。有很多信息从DOM里读不到比如字体渲染后的行高、渐变背景、阴影层次这些只有截图里看得出来。AI视觉理解的能力已经被严重低估了给它一张清晰的截图比给它500行代码更管用。第3条DOM归一化时慎用“强力压缩”。开始我做归一化下手太狠把所有嵌套结构一律拍平结果语义关系全丢了。AI分不清楚哪个区块是并排、哪个是嵌套生成出来的组件结构牛头不对马嘴。后来改成保留父容器和兄弟结构只压无意义的标签效果立竿见影。第4条按“交互类型”而不是“视觉区块”来切组件。一个视觉上浑然一体的卡片里面可能既有跳转链接、又有表单提交、还有悬浮交互拆成一个组件会让代码里的逻辑混杂拆成三个又破坏视觉完整性。模板里的折中方案是拆组件按视觉区块交互逻辑按“事件委托加数据属性”挂到对应节点上组件内部再用自定义Hook做逻辑分区。这样视觉和交互都能保住。第5条字体编码问题比想象中麻烦得多。很多站用的是图标字体比如Font Awesome或自家的Unicode映射直接拷贝那段CSS是废的因为字体文件本身有授权保护。模板的做法是识别所有i.icon类和Unicode字符自动替换成内联SVG图标颜色尺寸从CSS中提取这样外观接近但代码完全重写。第6条动态内容的“三类分治”。页面里的动态数据分三种用户输入内容、接口返回数据、定时刷新的状态类数据。这三种的mock方式完全不同用户输入内容要用静态示例填充接口数据要在组件里建立API层定时刷新数据要做成事件驱动。如果不区分直接全部静态化页面看起来一模一样但手脚全是断的。第7条不要忽略hover和focus状态。截图只能拍到静态状态交互状态全靠代码推断。模板里要求生成环节必须为每个可交互元素补充hover、focus、active三个状态的最小实现哪怕只是颜色和阴影变化。这个要求是从一次离奇的返工学到的——客户走查时把鼠标移上去一点反馈都没有直接打回。第8条响应式断点必须从目标页面里反推。不能想当然用常见的375、768、1024三档。实际项目中有个站点的断点是420、820、1180它的导航栏在820到1180之间是完全不同的形态用默认断点做出去直接错位。做法是采集时多采几个viewport尺寸的截图AI能看到不同宽度下的布局变化才能推导真实的断点体系。第9条校验环节算“相似度”要有合理的容差。我最初把像素相似度阈值拉高到98%结果被各种字体渲染差异折磨得死去活来。实践中发现95%是一个合理的平衡点低于95%大概率真有结构问题高于95%人眼看不出明显区别。交互覆盖率的90%阈值也是同理卡太死容易把AI的创造力磨光卡太松又容易丢交互。这套阈值我写进了模板配置里也建议你根据实际站点类型微调。第10条一定要保留“逆向重建档案”。目标站点的每一个页面、每一版截图、每一次生成结果和对应的反馈记录都按站点名和日期存档。这件事前期看着多余后期价值很大——客户改需求、领导问进度、同事来交接档案就是你的工作底稿也是模板持续迭代的养料。5. 常见问题排查速查表最后整理一份走查过程中高频出现的现象和对应解法直接对着症状查能省掉不少排查时间。现象可能原因解决思路生成页面的整体布局错位左右两块重叠归一化时丢失了弹性布局的宽度比例信息检查采集时的视口宽度是否过窄重新采集补充截图作参考图片大量403或显示不出原站做了防盗链或签名过期按模板规则替换为占位图并记录原始图片尺寸字体图标渲染成方块或乱码图标字体文件未迁移或授权受限改用内联SVG替换图标名用Unicode码点做标识页面能显示但点击无任何响应事件绑定缺失或在组件拆分时被丢弃回到可交互点标注结果重新对比交互覆盖率报告定位丢失项滚动加载列表只有首屏数据采集时未正确触发滚动加载事件检查页面是否有IntersectionObserver懒加载调大滚动等待时间重采不同页面间样式跳跃同一个按钮两种颜色全局样式抽取失败组件内硬编码了公共变量把颜色、圆角、间距类公共样式抽到global层组件内改用变量引用页面在移动端宽度下严重变形响应式断点体系推导错误用多个视口尺寸重新采集截图重新生成时附带全部尺寸截图生成的代码构建报错依赖缺失组件生成时依赖版本不匹配检查生成环节的依赖清单尽量锁定指定版本并在Prompt中声明页面相似度指标一直低于90%目标站点存在大量动画或动态背景这类页面不适合纯静态逆向改用组件级异步渲染方案处理动态区表单提交后页面报错接口地址被整体替换但参数结构不匹配还原生成前的接口数据结构统一保留原接口路径用Mock层挡数据这张表也是模板仓库里README的常驻内容每次遇到新问题我都会回填一行现在基本维持在二十条上下很多都是特定场景才会复现的冷门问题。这种“问题即资产”的思路比收藏夹里塞一百篇教程有用得多。最后再补充一点个人体会。把网站逆向重建做成可复制流水线这件事本质上是在对抗“低水平重复”。单次逆向遇到一个站点解决一个站点每天都很忙但积累为零做成模板之后处理过的每个页面、踩过的每个坑都在完善这套系统第二十个站点的工作量大概只有第一个的两成。如果你也经常接到“参考某某网站做一个”的需求与其每次从零开始不如花几天时间把自己的流程沉淀成模板。前期多花的那点时间会在后续每个项目里连本带利地还给你。