网页脚本 009:Next.js联合window.postMessage实现Dynamic Crawler

【Claude Code · VibeCoding】11|需求梳理:云枢智学 / 学员平台 第三章 · 项目实战以「云枢智学」学员平台为例,把业务目标拆成可执行的需求条目。 阅读详情

介绍

  • 方法论
    • 人工智能Chat一般建议使用Puppeteer,这可能和训练语料相关。但这种方法并不好用,使用Puppeteer进行动态爬取的情况下,需要考虑使用无头浏览器在服务端渲染页面,但这会显著增加复杂性和资源消耗(而且更重要的是,许多在线部署平台不支持这种方法,要用更复杂的处理方法,比如需要一个专门的爬虫服务器)。
    • 还有一些方法,先爬取静态界面,然后执行界面中的js文件来动态获取内容,但是感觉这种方法处理要更加麻烦一些(好处是不用脚本的方法了),如果页面大量使用JavaScript动态加载内容,由于js的加载和执行的时序问题,可能无法获取到完整数据。
    • 本文的方法是用脚本直接执行浏览器中的相关功能。通过与nextjs程序通信的方式传递数据,Tampermonkey 脚本返回打开页面的html代码(可以等待一会,保证页面加载完成)。

原理说明

window.postMessage
  • 使用window.postMessage进行最安全、标准的跨上下文通信。
Tampermonkey 脚本:
// ==UserScript==
// @name         My Script
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  与 Next.js 通信
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 监听来自页面的消息
    window.addEventListener('message', function(event) {
        if (event.origin !== 'https://your-nextjs-app.com') return;

        if (event.data.type === 'GET_DATA_FROM_SCRIPT') {
            // 回复数据
            event.source.postMessage({
                type: 'DATA_FROM_SCRIPT',
                data: 'Hello from Tampermonkey!'
            }, event.origin);
        }
    });
})();
Next.js 页面(客户端):
  • Next.js 应用:开发的前端应用,运行在页面的主 JavaScript 环境中。
'use client';

import { useEffect } from 'react';

export default function HomePage() {
  useEffect(() => {
    // 发送消息给 Tampermonkey 脚本
    window.postMessage({
      type: 'GET_DATA_FROM_SCRIPT'
    }, '*'); 

    // 接收来自 Tampermonkey 的回复
    const handleMessage = (event) => {
      if (event.origin !== 'https://your-nextjs-app.com') return;

      if (event.data.type === 'DATA_FROM_SCRIPT') {
        console.log('收到 Tampermonkey 数据:', event.data.data);
      }
    };

    window.addEventListener('message', handleMessage);

    return () => {
      window.removeEventListener('message', handleMessage);
    };
  }, []);

  return <div>Next.js 页面,正在与 Tampermonkey 通信</div>;
}

实现

  • 脚本会根据当前网站判断自己是「主脚本」还是「子脚本」:
    • 在 http://localhost:3000:「主脚本」监听 Next.js 页面发来的消息 → 用 GM_openInTab 打开目标网址 → 等待子脚本把 HTML 回传 → 再转发给页面。
    • 在其它网站:充当「子脚本」,自动在加载后延迟一段时间,把完整的 HTML 回传给主脚本。

完整代码

Tampermonkey 脚本
// ==UserScript==
// @name         Unified Background Fetcher (Auto Close)
// @namespace    http://tampermonkey.net/
// @version      2025-09-28
// @description  在 localhost:3000 发起请求,在目标网站采集 HTML 后返回并关闭标签页
// @author       You
// @match        http://localhost:3000/*
// @match        *://*/*
// @grant        GM_openInTab
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addValueChangeListener
// ==/UserScript==

(function() {
    'use strict';

    const originPage = "http://localhost:3000";

    // =====================
    // 主脚本逻辑 (运行在 localhost:3000)
    // =====================
    if (location.origin === originPage) {
        console.log("运行在主页面:", location.href);

        // 保存 tab 引用
        const tabRefs = {};

        // 监听 Next.js 页面消息
        window.addEventListener('message', (event) => {
            if (event.origin !== originPage) return;
            if (!event.data || event.data.type !== 'FETCH_URL') return;

            const url = event.data.url;
            console.log("收到页面请求,准备后台打开:", url);

            if (!tabRefs[url] || tabRefs[url].closed) {
                const tab = GM_openInTab(url, { active: false });
                tabRefs[url] = tab;
            }
            // tabRefs[url] = tab; // 记住这个标签页对象

            // 监听子脚本的抓取结果
            GM_addValueChangeListener("html_result_" + url, (name, oldValue, newValue) => {
                console.log("收到后台标签页数据:", url);

                // 把数据发回页面
                window.postMessage({
                    type: 'FETCH_RESULT',
                    url,
                    html: newValue
                }, originPage);

                // 关闭后台标签页
                if (tabRefs[url]) {
                    console.log("关闭后台标签页:", url);
                    tabRefs[url].close();
                    delete tabRefs[url];
                }
            });
        });
    }

    // =====================
    // 子脚本逻辑 (运行在目标网站)
    // =====================
    else {
        console.log("运行在目标网站:", location.href);

        // 延迟 5 秒钟等待页面渲染
        setTimeout(() => {
            try {
                const html = document.documentElement.outerHTML;
                GM_setValue("html_result_" + location.href, html);
                console.log("已回传 HTML:", location.href);
            } catch (e) {
                console.error("抓取失败:", e);
            }
        }, 5000);
    }
})();


Next.js 页面调用示例
'use client';
import { useEffect } from 'react';

export default function Monkey() {
  useEffect(() => {
    console.log("页面加载,发送抓取请求");

    // 请求 Tampermonkey 打开并抓取
    window.postMessage({
      type: 'FETCH_URL',
      url: 'https://www.baidu.com/'
    }, 'http://localhost:3000');

    const handleMessage = (event: MessageEvent) => {
      if (event.origin !== 'http://localhost:3000') return;
      if (event.data.type === 'FETCH_RESULT') {
        console.log("抓取结果:", event.data.url);
        console.log("HTML 内容预览:", event.data.html.slice(0, 200), "...");
      }
    };

    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, []);

  return <div>Next.js 页面,正在请求 Tampermonkey 抓取网页</div>;
}

在这里插入图片描述

在这里插入图片描述

注意事项

  • 目标网站如果跨域限制严重(iframe 不能访问),这种方式仍然可行,因为脚本运行在目标网站上下文中,可以直接读 DOM。
  • 第一次运行时,Tampermonkey 可能会提示「需要新权限(跨域访问)」→ 需要点击 允许。

在这里插入图片描述
在这里插入图片描述

  • 如果没有正确点击通过会自动加入到黑名单:

在这里插入图片描述在这里插入图片描述

NFS共享速度慢?麒麟系统性能调优5个关键参数实测对比 本文针对银河麒麟服务器系统上NFS共享速度慢的问题,通过实测对比分析了五个关键调优参数。重点探讨了rsize/wsize传输块大小、TCP/UDP协议选择、sync/async模式权衡等,并结合麒麟系统特性提供了具体的优化建议与配置示例,旨在帮助用户有效提升国产化环境下的文件共享性能。 阅读详情

相关推荐

告别路径打架!用Python实现CBS算法搞定仓库机器人调度(附完整代码)

本文详细介绍了如何使用Python实现CBS(Conflict-Based Search)算法解决仓库机器人调度中的路径冲突问题。通过多智能体路径规划(MAPF)技术,有效避免AGV在智能仓库中的碰撞和死锁,提供完整代码实现和工业场景优化技巧,帮助开发者快速构建高效的机器人调度系统。

weixin_30275415的博客 328

Web 版翻译者资料库

本项目是桌面版《翻译者资料库》的 Web 移植版,基于 Spring Boot 3.3、Thymeleaf、Bootstrap 5.3 与 MySQL 8.0 构建。它面向翻译写作提供资料、词汇、句库、文本工具、对照制作、查找、备份恢复及旧库迁移等功能,完整继承桌面版核心业务规则,支持一键启动与离线访问。

howard2005的专栏 134

Linux CentOS7文件系统(/dev/var)的容量扩充

原因是之前安装docker后,再想安装Nessus,系统说home、var文件系统的内存都不够。

JHoanna的博客 3225

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 333

多层感知机 Multilayer Perceptron | MLP

本文主要简单介绍了多层感知机的基本概念,优缺点,应用场景,建模时的注意事项,评价指标,实现方法,python示例和模型的参数等。

JasonH2021的博客 3万+

为什么你的SiC MOSFET仿真不准?可能是离子注入的‘沟道效应’在捣鬼(Silvaco BCA模块详解)

本文深入分析了SiC MOSFET仿真中离子注入沟道效应的关键影响,揭示了Silvaco BCA模块在模拟SiC晶向和角度参数时的核心设置要点。通过详细解析晶圆偏切与注入角度的等效关系,提供优化MOSFET沟道区注入仿真的五步实战方法,帮助工程师将阈值电压仿真误差从26%降低到5%以内。

weixin_26789847的博客 409

React 性能:memo / useMemo / useCallback

讲清 memo/useMemo/useCallback 的配合与边界,先测量再优化,避开常见过早优化。

JudithHuang的博客 325

【electron】- 从零到一:在electron-vite项目中集成better-sqlite3的工程化实践

本文详细介绍了在electron-vite项目中集成better-sqlite3数据库的完整工程化实践。针对原生模块的编译挑战,提供了从环境配置、路径规划、服务封装到IPC通信的解决方案,并重点解决了开发与生产环境的数据库路径分离及打包部署等核心问题,帮助开发者构建稳定高效的Electron桌面应用数据层。

weixin_29306571的博客 204

DSH (DeepSeek Harness) Windows 升级安装指南20261107

注意:如果在普通窗口执行 nvm 提示找不到命令,或执行 nvm use 提示 Access is denied,请务必关闭当前窗口,重新打开一个管理员CMD 执行上述完整路径命令。找到 .credentials.yaml,将其重命名为 .credentials.yaml.bak(备份并使其失效)。Node.js Storage Location:可改到非系统盘(如 D:\dev\nvm,避免路径含空格或中文)。打开文件资源管理器,进入 C:\Users<你的用户名>.dsh\。

fengye207161的博客 186

OpenCASCADE(OCC)读取 STEP 模型文件并在MFC中显示

OpenCASCADE(OCC)读取 STEP 模型文件并在MFC中显示

weixin_61900468的博客 1万+

基于潜在空间分数匹配的混合型表格数据合成方法

然而,在我们的模型中,β 预计会更小,因为我们不需要嵌入的分布精确地遵循标准高斯分布,因为我们还有一个额外的扩散模型。受 Transformer 在表格数据分类/回归任务中取得成功的启发,我们首先为每一列学习一个独特的标记器,然后将标记(列)级表示输入到 Transformer 中,以捕捉列之间错综复杂的关系。在第 4 节中,我们证明了通过这种设计,TABSYN 可以在不到 20 次函数评估(NFE)的情况下生成高质量的合成表格数据,这比其他基于扩散的表格数据合成方法要少得多。是标记器的可学习参数。

步子哥的博客 853

SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在

# SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在 > 这是一套基于 Spring Boot 的服装销售平台源码,配套 `db.sql` 建表脚本,业务覆盖商品展示、购物车、订单流转、收货地址、订单评价、商品评论、在线客服、轮播图和资讯。形态是**前后台双端**:前台是顾客逛的商城,后台是管理员管的控制台。本文带你看清里面有什么、怎么跑

面朝大海 226

Harness Engineering:让Coding Agent真正落地生产

本文将带你系统性地了解如何让Coding Agent真正落地生产,核心是依托(全球领先的持续交付、云成本管理、 feature flagging、安全治理一体化平台),结合企业级AIDD(AI-Driven Development)的工程化实践,构建一套可信赖、可观测、可扩展、可治理的Coding Agent落地体系。核心概念与理论基础:什么是Coding Agent?它和普通的AI代码补全工具(比如GitHub Copilot)有什么区别?什么是Harness Engineering?

移动开发前沿的博客 455

微信小程序-wxs

在微信开发者工具中右键创建.wxs后缀的文件。每个.wxs文件也是一个独立模块,同样使用导出内容。示例(文件return d;FOO: foo,bar: bar(外联定义参考官方文档)

dreams_dream的博客 335

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

使用echarts模拟甘特图

项目中需按时间段展示不同颜色的数据,通过解析时长并统计各类型总时长,结合预设颜色映射表(含自定义与默认色),动态生成ECharts图表。利用sumByTypeName聚合数据,为每类分配对应颜色,实现图例与柱状图的精准匹配,确保多时段、多类型数据可视化清晰准确。

uuai 28

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【技术专题】JavaScript 网页技术 - JavaScript 流程控制

小锋老师推出《一天学会JavaScript(无废话版)》视频教程,涵盖基础语法、流程控制、函数、数组对象、DOM操作及ES6新特性。内容精炼,配套课件与源码打包下载,助力快速入门。重点讲解if/else、switch、for/while循环、for...of/in遍历及break/continue使用场景,并通过成绩判断实例演示实际应用。适合零基础学习者高效掌握核心技能。

java1234的博客 159

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

基于 FastAPI+LangChain+LangGraph+Agent+Vue3+MySQL 的房产数据采集与房价预测分析平台

本文介绍一个完整的「房产数据采集+AI房价预测」全栈项目,涵盖FastAPI异步后端、LangGraph Agent智能问答、爬虫采集、机器学习预测与Vue3前端,实现从数据采集到AI交互的闭环。项目融合多技术栈,具备真实业务场景与生产级设计(如降级策略、流式输出、多模型对比),兼具简历亮点与答辩演示优势,可系统性提升工程能力,并附高频面试题解析,是理想的技术综合实践项目。

深耕开发,专注编程实战。分享源码解析、项目搭建、问题排查笔记,沉淀技术,持续更新。 225

Agent 的 ReAct、Plan、Execute、Reflection 模式

本文系统解析 Agent 的 ReAct、Plan、Execute、Reflection 四模式,揭示其核心为“下一步谁定”与“错了怎么发现”两大问题。ReAct 逐步决策,适合动态环境但易冗余;Plan 一次性规划,高效却惧变化;Execute 严格落地,需明确判据与失败策略;Reflection 事后校验,强化纠错闭环。四者协同:外层规划,执行中嵌入思考,每步后反思,连续失败才重规划,构建稳定可控的智能体工作流。

2401_89855466的博客 324

货运APP、货运小程序开发:网络货运平台与同城配送搬家系统实战

本文介绍一套完整的货运平台系统,涵盖货运APP、小程序、网络货运、同城配送、搬家预约等场景,基于SpringBoot+MyBatisPlus+MySQL技术栈,采用uni-app实现多端统一开发,配套TMS运输管理与物流管理系统,支持下单、派单、运输、结算全流程,适用于货运搬家、物流搬运与配送业务,可作为物流软件及TMS系统的参考实现。

juzige03的博客 217

Vue3 低代码移动表单设计器实战(二):缩放画布下的拖拽系统与树状级联数据结构

本文深入剖析Vue3低代码表单设计器在缩放画布下的拖拽失效问题,揭示SortableJS在CSS Transform下坐标崩溃的数学根源。通过自研独立视觉克隆壳层与逆向几何补偿算法,实现精准拖拽;采用扁平数据存储+运行时树状计算结构,解决级联依赖与深克隆难题,确保逻辑一致性与性能优化,为复杂低代码系统提供可复用的工程范式。

NanChen的博客 340

Vue-Router

本文详解前端路由原理与实现,以网易云音乐为例,介绍通过 vue-router 实现页面无刷新切换。核心步骤包括:安装模块、创建路由实例、注册应用、配置页面组件与路由出口。使用 router-link 实现声明式导航,结合 query 和 params 传参,支持模糊与精确匹配激活状态。强调 useRoute(读取参数)与 useRouter(执行跳转)的区别,帮助开发者掌握单页应用路由的核心机制。

2301_79245606的博客 339

LangGraph == 循环结构的实现

这是静态约束,不会参与运行时校验。主要作用是提升代码可读性、通过静态类型检查,同时帮助 LangGraph。也就是说,是否继续重试,在当前实现中主要由大模型决定,而不是由程序逻辑强制保证。因此,如果模型在多次工具调用失败后选择停止重试并生成最终回答,运行图不会阻止它。函数,也不再需要调用 add_conditional_edges()只要大模型持续返回工具调用,流程就会不断回到 llm_node。的缩写,即“推理 + 行动”架构。,运行时只负责判断具体走哪一条路径。

每天都要努力学习哦~~ 347

Vue 前端开发 AI 对话页面:流式消息渲染、文件上传

关键点是不能手动设置 Content-Type 为 multipart/form-data,必须由浏览器自动生成带有 boundary 的请求头,否则后端无法解析。思路:将对象序列化为 JSON 字符串,作为 FormData 的一个普通字段(如 formData.append(‘payload’, JSON.stringify(data))),后端接收该字段后再反序列化。若上传大文件(>10MB),需实现独立的分片上传接口,在提交对话前先获取文件 id 或 url,再随文本发送引用。移除输入框的禁用态;

2402_85729970的博客 386

Flux 架构:一个单向数据流库是怎么跑起来的

状态只有一份 + 数据单向流 + reducer 是纯函数 + 中间件链可组合 + 视图层声明式绑定。这 30 行就是这套思想的最小完整样本:两次useStore订阅、一次拿链式 dispatch、四个按钮对应四种 action(其中一种是 thunk 形态)。

sun_weitao的博客 108

纯 Go 写的 JS 引擎,跑分超过了 C 语言的 QuickJS

moejs 是一个纯 Go 编写的高性能 JavaScript 运行时,专为 Go 程序中的插件沙箱场景设计。发布于 2026 年 11 月,由 new-api 维护者 Calcium-Ion 开发,相较 C 版 QuickJS 快 35%,内存占用仅 81 KiB,单次调用仅 6.9 微秒。支持快速复用运行时、零拷贝解析、安全沙箱与 TypeScript 直接编译,通过 test262 80971 个用例零失败。适合高并发插件系统,如 AI 网关钩子处理,已在实际场景中实现请求吞吐量提升 8.6 倍。仓库

前端之虎陈随易 196

vue3 markdown编辑框与压缩包文件上传及预览

el-input v-model="form.author" placeholder="作者/组织" maxlength="50" clearable /><el-select v-model="form.category" placeholder="请选择标签" class="full-width"><el-select v-model="form.license" placeholder="请选择" class="full-width">'编辑技能' : '新建技能' }}</div>

每一篇博客都是对自己技术的沉淀 173
上一篇: 【LLM LangChain】AgentExecutor 创建带工具的Agent+加入BufferMemory+支持多用户记忆 demos
下一篇: 图片速览: AI-Agents毒害网络 A Whole New World: Creating a Parallel-Poisoned Web Only AI-Agents Can See
FakeOccupational
博客等级 码龄6年 2万+粉丝 1727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值