Rain Blog
Armbian 环境下安装并配置 Crawl4
### 前言:为什么 Armbian 与众不同? Crawl4AI 是一个强大的网页抓取工具,但它依赖的底层浏览器自动化库 Playwright 官方主要提供为普通电脑/服务器(x86_64 架构)编译的浏览器。我们的 Armbian 系统运行在 ARM 架构上,因此无法使用官方的自动安装程序。本指南的核心就是绕过这个限制,手动配置,让 Crawl4AI 在 Armbian 上完美运行。 ### 第一步:系统环境准备 (安装系统版浏览器) 我们不使用 Crawl4AI 自带的安装脚本,而是直接从 Armbian 的软件库中安装已经为 ARM 架构编译好的 Chromium 浏览器。 更新软件列表并安装 Chromium: Bash sudo apt-get update sudo apt-get install -y chromium-browser 获取浏览器路径: 安装完成后,运行以下命令找到它的可执行文件路径,并复制这个路径以备后用。 Bash which chromium-browser (通常路径为 /usr/bin/chromium-browser) ### 第二步:安装 Python 包并初始化环境 接下来,我们安装 Crawl4AI 的 Python 包,并进行一个关键的环境初始化步骤。 使用 pip 安装 Crawl4AI: Bash pip install crawl4ai 初始化 Playwright 环境 (但不下载浏览器): ...
rclone挂载谷歌网盘
运行 Rclone 官方安装脚本: 这个脚本会自动检测您的系统架构并下载安装最新稳定版的 Rclone。 Bash curl https://rclone.org/install.sh | sudo bash 验证安装: 运行以下命令查看版本号,如果成功显示版本信息,则表示安装成功。 Bash rclone version 测试配置: 运行以下命令,如果能列出您 Google Drive 根目录的文件和文件夹,说明配置成功! Bash rclone lsd gdrive: (注意:gdrive: 冒号不能少,gdrive 是您之前给远程连接起的名字)。 第二阶段:挂载 Google Drive 创建挂载点: 在您的主目录下创建一个文件夹,用来作为挂载点。 Bash mkdir -p ~/gdrive 执行挂载命令: Bash rclone mount gdrive: ~/gdrive --daemon rclone mount: 挂载命令。 gdrive:: 您配置的远程名称。 ~/gdrive: 本地挂载点目录。 --daemon: 让 rclone 在后台运行,这样您关闭 SSH 连接后挂载依然有效。 验证挂载: 使用 df -h 命令,您应该能看到一个类型为 fuse.rclone 的新文件系统。 使用 ls -l ~/gdrive 命令,您应该能看到您 Google Drive 里的文件。 ...
vaultwarden直接deb文件安装
vaultwarden.deb 包只包含了后端程序,它需要另一个独立的包来提供前端界面。 ## 解决方案 🛠️ 最直接的解决方法就是安装缺失的前端包。 方案一:安装缺失的前端包 (推荐) 您需要回到最初下载 .deb 包的那个页面,找到并下载 vaultwarden-webvault 这个包。 下载前端包 第三方软件包 后端包 前端包 登陆:rain1226:ofen 在您下载 vaultwarden_1.34.1-1+1.1_amd64_ubuntu22.deb 的地方,应该还有一个类似下面这样命名的文件: vaultwarden-webvault_2024.5.0_all.deb (版本号 2024.5.0 可能会不同,架构通常是 all 因为它只包含网页文件)。 安装前端包 使用 dpkg 命令安装它。这个包通常没有复杂的依赖。 Bash sudo dpkg -i vaultwarden-webvault_xxxx_all.deb (请将 xxxx 替换为您下载的实际文件名) 重启 Vaultwarden 服务 安装好前端文件后,它们就会出现在后端程序期望的位置。现在只需重启服务即可。 Bash sudo systemctl restart vaultwarden 再次检查状态 等待几秒钟,然后再次检查服务状态,这次应该就是 active (running) 了。 Bash sudo systemctl status vaultwarden Vaultwarden 的配置通常在 /etc/vaultwarden.cfg(取决于打包方式)。 打开这个文件,找到并修改 SIGNUPS_ALLOWED=true 为 SIGNUPS_ALLOWED=false,然后重启服务 sudo systemctl restart vaultwarden。
编译Rust之Stump电子书库
这就是编译和部署中最经典的困境: 编译时:我们需要一个新环境(Debian 12),因为它有程序源码需要的、新的开发工具和库(比如 libglib-2.0 >= 2.70)。 运行时:我们需要产物能在一个旧环境(Debian 11)上运行,因为它只有旧版的系统基础库(glibc)。 幸运的是,Rust 语言的工具链非常强大,它提供了一个完美的解决方案来解决这个悖论。 最终解决方案:静态编译 (Static Compilation using MUSL) 我们的最终目标是生成一个不依赖任何系统库的、完全独立的“绿色”程序。这样它就不再关心你的 VPS 是 Debian 11、12 还是其他什么系统了。 这个技术叫做“静态编译”,我们将使用一个名为 MUSL 的C语言基础库来替代主流的 GLIBC。 GLIBC (动态链接):程序运行时,需要去“借用”操作系统的基础库。操作系统版本不对,就借不到,程序报错。 MUSL (静态链接):在编译的最后一步,把所有需要的基础库功能,像“干粮”一样,全部打包进最终的程序文件里。程序运行时自给自足,完全不依赖外部系统。 这完美地契合了你最初“单文件,占用资源较少,不需要安装依赖”的设想。 终极操作指南:编译一个真正的静态程序 我们将继续使用 Debian 12 作为我们的编译环境(因为它有我们需要的新版开发工具),但我们会告诉编译器,我们的最终目标是生成一个基于 MUSL 的静态程序。 第一步:彻底清理旧环境 和上次一样,我们先删除旧的 stump-builder 容器,确保从一个干净的状态开始。 如果你还在容器里,请 exit。 在你本地电脑的终端运行: Bash docker stop stump-builder docker rm stump-builder 第二步:启动 Debian 12 编译容器 这一步和上次完全一样,我们仍然需要 Debian 12 的新环境来满足编译时的依赖。 Bash docker run -it \ --name stump-builder \ -v "$(pwd)":/build \ --env "HTTP_PROXY=http://172.17.0.1:7890" \ --env "HTTPS_PROXY=http://172.17.0.1:7890" \ debian:12-slim \ /bin/bash 第三步:在 Debian 12 容器内执行全新的编译步骤 进入容器后,请一步步执行以下命令。注意,依赖包和编译命令都发生了变化。 ...
CSS选择器详解
首先,一个核心概念要明确: CSS选择器是一套独立的“语言”,它本身与Python或JavaScript无关。 无论你在哪里使用它,语法规则都是完全一样的。 在Python的BeautifulSoup里,你把选择器字符串传给 soup.select('...') 函数。 在JavaScript里,你把同样的字符串传给 document.querySelectorAll('...') 函数。 在CSS样式表里,你直接使用它来定义样式。 所以,学会了怎么写选择器,你就等于掌握了一项在所有这些技术中通用的技能。 JavaScript中如何使用CSS选择器 在JS脚本(尤其是在浏览器控制台里调试时),你主要会用到这两个函数: document.querySelector('你的选择器') 作用:返回匹配到的 第一个 元素。 特点:如果找不到,返回 null。当你确定只有一个目标时,用它很方便。 document.querySelectorAll('你的选择器') 作用:返回匹配到的 所有 元素,以一个列表(NodeList)的形式。 特点:这是我们爬虫和调试时最常用的!它和Python里的 soup.select() 功能几乎完全一样。如果找不到,返回一个空列表。 这是你在将选择器放入Python代码前,进行测试的最佳方式! CSS选择器参数写法“速查宝典” 下面,我为你整理了一份从入门到精通的CSS选择器写法“秘笈”,并结合 docs.crawl4ai.com 的例子来说明。 1. 基础选择器 (The Basics) 类型 语法 例子 (针对crawl4ai) 解释 标签 tag h1 选取所有 <h1> 标签。 类名 .classname .terminal-mkdocs-side-nav-item 选取所有 class 属性包含这个类名的元素。 ID #idname #Introduction 选取 id 属性等于 Introduction 的元素(ID在页面中应唯一)。 2. 组合选择器 (Relationships) 这是最强大的部分,用来描述元素之间的层级关系。 类型 语法 例子 解释 后代 A B ...
n8n使用code节点清洗数据
crawl4ai真实数据结构,raw_markdown 的正确路径是: item.json.results[0].markdown_v2.raw_markdown 我们来分解一下这个正确的路径: item:这是 n8n 传给 Code 节点的单个数据项,它的顶层就有一个叫 "json" 的对象。 .json:进入这个 "json" 对象。 .results:在 "json" 对象内部,找到 "results" 字段,它是一个数组 [ ... ]。 [0]:从这个数组中,取出第一个元素(因为编号从0开始)。 .markdown_v2:在这个元素对象中,找到 "markdown_v2" 字段。 .raw_markdown:最后,从 "markdown_v2" 对象中,取出我们最终需要的 "raw_markdown" 文本。 你之前的尝试都非常接近,只是因为 crawl4ai 的输出实际上被包裹在了另一层 json 对象里,这是我们之前无法预料到的。你通过 console.log 把它找了出来,这正是最专业的调试方法! 最终的 n8n Code 节点代码 现在,请将你的 Code 节点代码完整替换为下面这个最终正确版本。它使用了正确的路径,并且依然保持了“健壮性”,可以防止因为未来可能的抓取失败而导致工作流崩溃。 JavaScript // 获取上一个节点传入的所有数据项 const items = $input.all(); // 遍历每一个数据项进行处理 for (const item of items) { // 使用我们最终确定的正确路径来安全地访问数据 let text = item.json?.results?.[0]?.markdown_v2?.raw_markdown; if (text) { // --- 最终清理流程 --- // 1. 【关键新增步骤】将字符串 "\\n" 替换为真正的换行符 \n // 这是解决你看到 `\n` 而不换行的核心 text = text.replaceAll('\\n', '\n'); // 2. 定义一个更全面的“垃圾内容”关键词黑名单 const junkKeywords = [ '分类', '图像来源', '图像加注文字', '补充报导:BBC国际部', 'Article Information', 'Author,', 'Role,', '热读', 'End of 热读', '更多相关内容', '热门内容', '特别推荐', 'BBC值得信赖的原因', '© 2025 BBC' ]; // 3. 先用更强的正则表达式,移除所有图片和链接的 Markdown 标记 text = text.replace(/(!?\[[\s\S]*?\]\([\s\S]*?\))+/g, ''); // 4. 【核心改进】按行处理,用更严格的规则过滤 const lines = text.split('\n'); const cleanedLines = lines .map(line => line.trim()) // 去除每行首尾的空格 .filter(line => { // 规则a: 过滤掉空行 if (line.length === 0) return false; // 规则b: 过滤掉无意义的符号行 if (line === '*' || line === '###') return false; // 规则c: 过滤掉类似 "1. 1" 或 "10. 10" 这样的错误行 if (/^\d+\.\s\d+$/.test(line)) return false; // 规则d: 过滤掉看起来像单独日期的行 if (/^\d{4}年\d{1,2}月\d{1,2}日$/.test(line) || /^\d+\s小时前$/.test(line)) return false; // 规则e: 如果行内包含任何一个黑名单关键词,就过滤掉它 if (junkKeywords.some(keyword => line.includes(keyword))) return false; return true; // 保留所有“干净”的行 }); // 5. 将干净的行重新组合,并整理段落格式 let cleanedText = cleanedLines.join('\n'); cleanedText = cleanedText.replace(/\n{3,}/g, '\n\n'); // --- 清理流程结束 --- item.json.cleaned_markdown = cleanedText.trim(); } else { item.json.cleaned_markdown = "处理失败:未能在指定的路径中找到内容。"; } } // 返回被修改后的数据项 return items;
正确的Python Code Crawl4ai节点脚本
正确的 Python Code ___Crawl4ai 节点脚本 这次的方案不再依赖任何需要从外部安装的第三方库,而是完全使用了 n8n 的 Python (Pyodide) 环境内置的、专门为此设计的工具。它绕开了所有关于操作系统权限和模块缺失的限制。 请将 Code 节点中的代码完整替换为以下内容: Python # 这是在 Pyodide 环境中进行网络请求的正确方法 import json # 1. 导入 Pyodide 内置的 http 模块 import pyodide.http # 2. 定义 API 请求所需的所有参数 api_url = 'https://name-crawl4ai.hf.space/crawl_sync' api_token = 'Your token' target_urls = ['https://example.com/'] # 3. 构建请求头 (Headers) 和请求体 (Payload) headers = { 'accept': 'application/json', 'Authorization': f'Bearer {api_token}', 'Content-Type': 'application/json' } payload = { "urls": target_urls } # 4. 使用 pyodide.http.pyfetch 发送请求 # 这是一个异步函数, 所以我们必须在它前面加上 await print("正在使用 Pyodide 内置的 pyfetch 发送 API 请求...") try: response = await pyodide.http.pyfetch( api_url, method='POST', headers=headers, # pyfetch 的 body 参数需要一个字符串, 所以我们用 json.dumps 转换 body=json.dumps(payload) ) # 5. 检查响应是否成功 if not response.ok: # 异步获取错误文本 error_text = await response.string() raise Exception(f"HTTP 错误! 状态码: {response.status}, 详情: {error_text}") print("API 请求成功,已获取数据。") # 6. 异步获取并解析 JSON 数据 data = await response.json() # 7. 按照 n8n 的格式要求返回数据 return [{"json": data}] except Exception as e: print(f"请求失败: {e}") raise e 关键改动解读 import pyodide.http: 我们导入的是 Pyodide 环境特有的模块。 ...
HF部署的Crawl4AI API 端点用途详解
我们可以把这些端点分为两大类:核心爬取功能和辅助功能。 核心爬取功能 1. POST /crawl_sync (同步爬取 - 您正在使用的) 用途: 这是最直接、最简单的爬取方式。 工作模式 (同步): 您发送一个包含目标网址的请求,然后您的程序会一直等待,直到服务器完成所有的工作(启动浏览器、加载页面、提取内容),最后服务器将完整的结果一次性返回给您。 好比: 去快餐店点餐。您点单、付钱、在柜台前等待,然后直接拿到您的汉堡。一次搞定。 适用场景: 非常适合测试、快速获取单个页面的结果,或者在您自己的脚本不介意等待几秒到几十秒的情况下使用。 2. POST /crawl 和 GET /task/{task_id} (异步爬取 - 两步法) 这两个端点需要组合使用,提供了一种更高级、更强大的工作模式。 用途: 处理可能耗时很长的爬取任务,避免请求超时。 工作模式 (异步): 第一步 (POST /crawl): 您先发送一个爬取请求。服务器收到后,不会马上开始爬取,而是立即返回一个任务ID (task_id),好比给您一个取餐的号牌。 第二步 (GET /task/{task_id}): 您拿到 task_id 后,可以过一会儿再用这个 ID 去调用 /task/{task_id} 接口,查询任务的进度(例如:排队中、处理中、已完成、失败)。如果任务已完成,这个接口就会返回最终的爬取结果。 好比: 去一家高级餐厅点一道需要精心烹制的菜。您点单后,服务员给您一个订单号,您可以先做点别的事情,隔一段时间再凭订单号询问菜做好了没有。 适用场景: 构建复杂的应用程序,需要同时发起多个爬取任务而不希望程序被卡住;或者当您要爬取的网站非常庞大,预计会花费几分钟甚至更长时间时,使用异步模式可以防止您的请求因为超时而失败。 3. POST /crawl_direct (直接爬取) 用途: 从命名上看,它很可能也是一个同步端点,类似于 /crawl_sync。 推测: “Direct” 可能意味着它绕过了一些高级的内容处理(比如复杂的 Markdown 转换、内容过滤或文章提取),直接返回更“原始”的页面数据(例如,只提取纯文本或基础HTML)。这会让它的处理速度更快,但返回的信息没有经过深度加工。 辅助功能 4. GET /health (健康检查) 用途: 这是一个标准的接口,用于监控服务是否还“活着”。 工作模式: 当您访问这个端点时,如果服务正常,它会返回一个成功的响应(例如 {"status": "ok"})。自动化监控系统会定期调用这个接口,如果发现调用失败或超时,就会发出警报,提醒管理员服务可能出问题了。 ...
API 请求映射到 n8n
如何将任何代码(无论是 curl、Python 还是 JavaScript)中的 API 请求,映射到 n8n 的 HTTP Request 节点上。 第一步:理解一个 API 请求的“四要素” 无论用什么工具,一个标准的 HTTP API 请求(特别是 POST 请求)通常都由四个核心部分组成,就像寄一个快递一样: 方法 (Method): 你想让服务器做什么操作。(POST, GET, PUT, DELETE 等) 好比: 告诉快递员你是要“寄件”(POST) 还是“查件”(GET)。 网址 (URL): 你要把请求发送到哪里。 好比: 快递包裹上的“收件人地址”。 请求头 (Headers): 关于这次请求的“元数据”或“说明书”。 好比: 快递单上的附加信息,比如“内含易碎品”(Content-Type)、“寄件人身份证号”(Authorization)。它描述的是这个包裹本身,而不是里面的东西。 请求体 (Body): 你实际发送给服务器的数据。 好比: 你要寄送的“包裹里的物品”。 n8n 的 HTTP Request 节点界面,就是围绕这“四要素”设计的,只不过是用图形化的方式来呈现。 第二步:将脚本代码与“四要素”对应 让我们以我们最终成功的 curl 命令为例,因为它最能清晰地体现这四要素: Bash curl -X POST \ 'https://rain1226-crawl4ai.hf.space/crawl_sync' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer password' \ -d '{ "urls": ["https://www.python.org"], "crawler_options": {} }' 我们来分解这个命令: ...
从搜狗双拼切换到小鹤双拼面
零声母音节的处理方式(这是最根本的区别)。 部分韵母的键位定义。 下面我将为您详细拆解,并提供记忆方法,助您平稳过渡。 一、最大的不同:零声母的处理方式 这是您需要建立的第一个新习惯,也是小鹤方案高效的原因之一。 搜狗双拼 (旧习惯): 处理零声母音节(如 a, an, ang, o, ou 等)时,需要先按下一个虚拟的“零声母引导键”,通常是 O 键。 输入“安”(an):需要按 O + J (J是搜狗方案里an的键位)。 输入“昂”(ang):需要按 O + D (D是搜狗方案里ang的键位)。 小鹤双拼 (新习惯): 彻底抛弃了零声母引导键。直接将零声母音节的第一个字母视为声母。 输入“安”(an):直接按 an 所在的键,即 J 键(a在A,n在N,所以an双拼在J)。 输入“昂”(ang):直接按 ang 所在的键,即 K 键。 输入“爱”(ai):直接按 ai 所在的键,即 D 键。 您需要做的改变: 忘记 O 键!以后凡是遇到 a, e, o 开头的音节,就把它当成一个普通的双拼音节直接输入即可。这是最核心、最重要的一个转变。 二、需要重新记忆的韵母键位 许多键位在两个方案中是相同的,这会减轻您的学习负担。我们重点关注那些发生了变化的键位。 下表清晰地列出了所有不同点,以及帮助您记忆的“小鹤口诀”提示。 韵母 搜狗双拼键位 (旧) 小鹤双拼键位 (新) 记忆提示与口诀(重点看) 韵母 搜狗双拼键位 (旧) 小鹤双拼键位 (新) 记忆提示与口诀(重点看) ai L D 爱(ai)戴(dài) -> ai 在 D an M J 安(an)静(jìng) -> an 在 J ang D K 昂(áng)首挺胸看(k) -> ang 在 K ianguang K L 姑娘(niáng)靓(liàng) -> iang 在 L ong S H 轰(hōng)隆隆 -> ong 在 H iong S Y 穷(qióng)困潦倒用(y)钱 -> iong 在 Y ing H Y 英(yīng)雄 -> ing 和 iong 都在 Y in J N 因(yīn)为(n) -> in 在 N (本身就是N) un Y P 温(wēn)柔一刀劈(pī) -> un 在 P 快速总结您需要重点练习的8个新键位:D, J, K, L, H, Y, N, P。 ...