小报童阅读太痛苦?我用n8n + Crawl4AI一键下载所有文章
小报童阅读太痛苦?我用n8n + Crawl4AI一键下载所有文章
小报童阅读太痛苦?我用n8n + Crawl4AI一键下载所有文章 小报童阅读太痛苦?我用n8n + Crawl4AI一键下载所有文章 Modified July 16, 2025 Audio or video is not supported Please download the file and open it with the appropriate software. 小报童.mp4 · 106.17MB 小报童 00:00 认证信息是通过 Crawl4AI 的browser config中的 HTTP 请求头配置的: Code block JSON Copy { "headers": { "authorization": "Bearer {{ $json.xiaobot authorization }}", "user agent": "Mozilla/5.0 ..." } } 这样浏览器发出的所有请求都会携带正确的认证信息。 2、拦截 XHR 请求 初始化数据存储和拦截 XHR 请求 Code block JavaScript Copy window.apiData = []; const originalXHR = window.XMLHttpRequest; window.XMLHttpRequest = function() { const xhr = new originalXHR(); const originalOpen = xhr.open; const originalSend = xhr.send; // 重写 open 方法,记录请求 URL xhr.open = function(method, url) { this. url = url; return originalOpen.apply(this, arguments); }; // 重写 send 方法,拦截小报童 API 响应 xhr.send = function(data) { if (this. url && this. url.includes('api.xiaobot.net')) { const originalOnReadyStateChange = this.onreadystatechange; this.onreadystatechange = function() { if (this.readyState === 4 && this.status === 200) { try { const data = JSON.parse(this.responseText); window.apiData.push(data); } catch(e) { // 忽略解析错误 } } if (originalOnReadyStateChange) { originalOnReadyStateChange.apply(this, arguments); } }; } return originalSend.apply(this, arguments); }; return xhr; }; 3、触发内容加载 Code block JavaScript Copy // 触发 document.querySelector('div.active')?.click(); // 等待初始加载 await new Promise(resolve = setTimeout(resolve, 5000)); 4、智能滚动加载 最初我用了简单的循环滚动 20 次,但后来优化为动态检测,获取所有文章: Code block JavaScript Copy let lastApiCount = 0; let noNewDataCount = 0; for(let i=0; i<50; i++) { // 滚动到页面底部触发加载 window.scrollTo(0, document.body.scrollHeight); // 等待数据加载 await new Promise(resolve = setTimeout(resolve, 5000)); // 检查是否有新数据 if(window.apiData.length === lastApiCount) { noNewDataCount++; if(noNewDataCount = 3) break; // 连续3次无新数据则停止 } else { noNewDataCount = 0; lastApiCount = window.apiData.length; } } 具体参数参见官方文档:Browser, Crawler & LLM Configuration (Quick Overview) 5、实际运行结果示例 经过上述步骤,Crawl4AI 会返回如下格式的数据 Code block SQL Copy [ { "success": true, "results": [ { "url": "https://www.xiaobot.net/p/AIProgram", "html": "<div class='crawl4ai result' ..</div ", "success": true, ... "js execution result": { "success": true, "results": [ { "success": true }, { "success": true }, { "success": true }, { "success": true }, { "articles": [ { "id": "4c905e05 4bd8 4d0e 9f24 583899265c74", "title": "加餐 | 微信公众号引流名片", "content": "<p <strong 最终效果图</strong </p <img src=\"https://static.xiaobot.net/file/2025 04 05/490728/e4105883b0e7544775ca80c315d3d751.webp\" <p </p ...</p ", "published at": "2025 04 05T13:56:12.000000Z", "tags": ["foo", "bar"] }, { "id": "9bb79a03 ab17 4e9a 8bb8 330fb1994838", "title": "加餐 | 飞机大战", "content": "<p 最终效果图 </p <img src=\"https://static.xiaobot.net/file/2025 04 05/490728/5f632d47a646be592f6a1dd83878fcc1.png\" ...</p ", "published at": "2025 04 05T13:55:10.000000Z", "tags": [] }, // ... 更多文章 ], "totalCount": 58, "metadata": { "timestamp": "2025 07 15T14:06:48.104Z", "source": "xiaobot", "totalApiCalls": 3 } } ] }, ... "markdown": { "raw markdown": "", "fit markdown": "", "fit html": "" } } ], "server processing time s": 45.72398042678833, "server memory delta mb": 2.02734375, "server peak memory mb": 186.32421875 } ] 我们主要需要观察的是 js execution result 这个字段的值,这个字段里的数据我将它结构化了。可以看到,每篇文章都包含完整的标题、HTML内容、发布时间和标签,这正是我们需要的结构化数据。 三)阶段三:文章处理与保存 数据获取后,需要转换为用户友好的格式: • 使用 Item Lists 节点拆分文章数组 • Loop Over Items 逐个处理每篇文章 • HTML to Markdown 转换格式 • 优化文件命名规则 • 批量保存为本地文件 五、实战踩坑 一)坑1:Docker 中的 headless 配置 最初设置headless: false,结果在 Docker 环境中报错: Code block Plain Text Copy Error: Failed to launch the browser process 解决方案:改为headless: true。在服务器环境中,headless 模式是必须的。 二)坑2:滚动容器选择错误 我一开始用的是容器滚动: Code block JavaScript Copy const container = document.querySelector('.posts'); Browser, Crawler & LLM Configuration (Quick Overview) Audio or video is not supported Please download the file and open it with the appropriate software. 小报童.mp4 · 106.17MB 小报童 00:00 Audio or video is not supported Please download the file and open it with the appropriate software. 小报童.mp4 · 106.17MB 小报童 00:00 认证信息是通过 Crawl4AI 的browser config中的 HTTP 请求头配置的: 这样浏览器发出的所有请求都会携带正确的认证信息。 2、拦截 XHR 请求 初始化数据存储和拦截 XHR 请求 3、触发内容加载 4、智能滚动加载 最初我用了简单的循环滚动 20 次,但后来优化为动态检测,获取所有文章: 具体参数参见官方文档:Browser, Crawler & LLM Configuration (Quick Overview) Browser, Crawler & LLM Configuration (Quick Overview) 5、实际运行结果示例 经过上述步骤,Crawl4AI 会返回如下格式的数据 我们主要需要观察的是 js execution result 这个字段的值,这个字段里的数据我将它结构化了。可以看到,每篇文章都包含完整的标题、HTML内容、发布时间和标签,这正是我们需要的结构化数据。 三)阶段三:文章处理与保存 数据获取后,需要转换为用户友好的格式: • 使用 Item Lists 节点拆分文章数组 • Loop Over Items 逐个处理每篇文章 • HTML to Markdown 转换格式 • 优化文件命名规则 • 批量保存为本地文件 五、实战踩坑 一)坑1:Docker 中的 headless 配置 最初设置headless: false,结果在 Docker 环境中报错: 解决方案:改为headless: true。在服务器环境中,headless 模式是必须的。 二)坑2:滚动容器选择错误 我一开始用的是容器滚动: 结果只能获取第一页数据。后来发现小报童的无限滚动监听的是 window 对象,不是容器: 这个改动让成功率从10%提升到100%。 六、最终效果:一键获取所有文章 现在整个流程只需要: 1. 配置专栏 URL 和 token 2. 点击"Execute workflow" 3. 等待3 5分钟 4. 获得 X 篇格式化的 Markdown 文章 每篇文章都包含完整的内容、标题和发布时间。文件名清晰易懂。可以用任何 Markdown 编辑器打开。 文件输出结构: 📌 使用须知 1. 仅用于已购买的付费内容 2. 不得二次分发或商业利用 3. 尊重原作者版权 使用须知 1. 仅用于已购买的付费内容 2. 不得二次分发或商业利用 3. 尊重原作者版权 🧠 扩展思路 这个方案不仅适用于小报童,稍作修改还可以应用于其他平台。 核心思路是通用的:找到 API → 分析认证 → 自动化抓取 → 格式转换 扩展思路 这个方案不仅适用于小报童,稍作修改还可以应用于其他平台。 核心思路是通用的:找到 API → 分析认证 → 自动化抓取 → 格式转换 七、反思:数据自由的价值 完成这个工作流后,我有几个深刻的感悟: 工具组合的威力。 n8n 的可视化编排 + Crawl4AI 的专业抓取能力,展现了no code 与专业工具结合的巨大潜力。非技术用户也能构建复杂的自动化流程。 用户体验的重要性。 一个真正好的产品应该让用户方便地导出自己的数据。数据锁定从来不是好的商业策略。 自动化的价值。 从手动复制粘贴到一键完成,效率提升何止百倍?更重要的是,自动化让我们能把精力集中在真正重要的事情上。 开放数据的意义。 数据在用户手中才能发挥最大价值。我可以搜索、标注、整理、分析这些内容,创造出远超原始形态的价值。 🎯 最后,我想说: 真正的数字化不是把内容锁在平台里,而是让用户能够自由地使用自己的数据。 技术应该服务于人,而不是束缚人。当我们掌握了工具,就掌握了自由。 完整的工作流配置文件和详细教程,我已经开源在 GitHub 了。公众号后台回复 “小报童”,即可免费获取工作流模版,希望能帮助到有同样需求的朋友们。 最后,我想说: 真正的数字化不是把内容锁在平台里,而是让用户能够自由地使用自己的数据。 技术应该服务于人,而不是束缚人。当我们掌握了工具,就掌握了自由。 完整的工作流配置文件和详细教程,我已经开源在 GitHub 了。公众号后台回复 “小报童”,即可免费获取工作流模版,希望能帮助到有同样需求的朋友们。 我是林月半子,关注我,带你一起挖掘工作流自动化的无限可能。 🔗 原文链接:https://mp.weixin.qq.com/s/usm0idRVQjLRJ5UZIWUT5w ⏰ 发布时间:2025 07 16 09:25:00 (UTC+8) 作者:林月半子的AI笔记 😅 花钱买知识,却连复制粘贴都被限制——这合理吗? 花钱买知识,却连复制粘贴都被限制——这合理吗? 作为小报童的付费用户,我每月为优质内容付费,但有一个荒谬的现象: 我可以花钱购买内容,却不能自由使用这些内容。 想复制一段文字做笔记?对不起,请手动一个字一个字敲。 想搜索历史文章?抱歉,搜索功能形同虚设。 想导出自己购买的内容?不存在的,数据永远锁在平台里。 更可怕的是,一旦作者删除内容或平台关闭,你的投资就彻底打水漂。 你说你付费了?抱歉,你买的只是"临时访问权"。 既然和平台讲道理行不通,那就让技术为用户发声。 作为一个程序员,我决定用技术手段解决这个问题。 但具体怎么做?是直接爬页面,还是有更优雅的方案? 首先,我需要了解小报童是怎么加载数据的... 一、技术调研:发现隐藏的 API 接口 说到研究数据加载,我想起前几天的一次痛苦经历。 上周想把某个专栏的精华内容整理成学习笔记,结果发现这是个噩梦: 打开第一篇文章,发现内容无法直接复制粘贴 → 只能截图保存 → 用 OCR 工具识别文字 → 手动校对错误 → 整理到笔记软件... 处理了十几篇后我彻底崩溃了:OCR 识别准确率不高,格式乱七八糟,这样下去得花一整天! 突然灵光一闪:既然前端能显示这些数据,那背后一定有 API 在工作! 也许我能直接批量获取数据,然后统一处理? 打开 Chrome 开发者工具,点击“Network”标签,刷新页面... 哇!一个完美的 API 请求映入眼帘: 返回的 JSON 数据结构简直美得不行: content字段里就是完整的 HTML 内容!这不就是我想要的数据源吗? 但是等等...那个sign参数是什么鬼? 看到这个 sign 参数,我的第一反应是尝试让 AI 逆向分析,试图找到签名算法... 但,花了两个小时,毫无进展。 算了,先用最笨的方法试试看。 二、第一次尝试:手工复制大法 既然暂时搞不定动态签名,我就用最朴素的方法:手动复制请求。 也许能先解决燃眉之急,后面再想办法优化。 在 n8n 里创建 HTTP Request 节点,把 cURL命令粘贴进去。运行!成功获取到一页数据。 然后...我需要翻页。再复制一次。再运行一次。 第三页...第四页... 当我复制到第十页的时候,我意识到这个方法简直是在折磨自己。260+篇文章,每页 20 篇,这得复制多少次? 三、方案选择:Crawl4AI 破解签名难题 就在我准备放弃纯 API 方案时,一个想法浮现:既然我破解不了签名, 为什么不让浏览器帮我做这件事? 这时候,Crawl4AI 走进了我的视野 Crawl4AI 📌 这不是普通的网页抓取工具。它能够: • 执行 JavaScript 代码 • 拦截 XHR 请求 • 模拟真实用户行为 • 处理动态加载内容 完美!正是我需要的。 这不是普通的网页抓取工具。它能够: • 执行 JavaScript 代码 • 拦截 XHR 请求 • 模拟真实用户行为 • 处理动态加载内容 完美!正是我需要的。 核心思路很简单:既然我无法构造动态签名,那就让浏览器帮我做这件事。通过拦截 XHR 请求,我可以捕获所有 API 响应,而不需要关心签名逻辑。 首先在本地安装 Crawl4AI,这里特别需要注意的是版本号,旧版本走的是 task 模式,我这里直接使用的新版本 同时确保 n8n 环境准备就绪: 关键配置说明: • v $(pwd)/xiaobot:/tmp: 将本地 xiaobot 目录映射到容器的 /tmp,导出的文章将保存在本地 xiaobot 文件夹中 • e GENERIC TIMEZONE=Asia/Shanghai: 设置时区,确保文件时间戳正确 启动后访问 http://localhost:5678 即可开始构建工作流。 四、工作流架构:三步走策略 整个自动化流程分为三个阶段: 一)阶段一:配置专栏参数 这里我做了变量化处理。只需要两个参数: • target url: 小报童专栏地址 • xiaobot authorization: 认证 token (用于 HTTP 请求头) 1、具体配置示例 在 n8n 的 Set 节点中,按以下格式配置: 2、如何获取 Authorization token 1. 登录小报童网站 2. 打开 Chrome 开发者工具 (F12) 3. 在 Network 标签页中找到 API 请求 4. 在 Request Headers 中复制 Authorization 字段的值(注:填写时需去掉 Bearer) 为什么要变量化?因为不同专栏的 URL 和 用户 token 不同,这样设计让工作流具备通用性。 二)阶段二:抓取小报童文章 这是整个工作流的核心。Crawl4AI 配置包含几个关键步骤: 1、设置认证信息