skip to content
仙人掌主题

N8N + Claude Code:自动获取B站热榜、保存选题Agent!

/ 14 min read

1. 项目和课程介绍

本期教程,我们会开发一个具有以下功能的agent:

  1. 自动获取B站热门实时数据

  2. 能够与AI沟通讨论选题

  3. 自动保存标题库到SupaBase的数据库当中,作为我们的选题库

这是前端的最终页面展示:

Agent是使用N8N进行开发。我们将它作为我们的服务在后台调用,我们在外套了一个壳。也就是说,人家是 API 套壳,我们是N8N的Agent套壳。

需要注意,我们这节课主要是讲的是如何将 agent 和我们自己的产品、以及supabase 结合起来,让它作为我们的一个服务。这是我们这个课程的一个核心。 至于 N8N的详细讲解,不是我们几节课程能够说得明白的。如果你想深入了解N8N,你需要去看更多一些 YouTube上的视频,并且尝试手动搭建。

2. 准备工作

我们首先来完成这个项目的一些准备工作

1. 注册N8N

我们使用到的需要首先你得去注册,登录注册一个N8N的账号。它是有14天的一个免费的使用权限的学习。我们这个课程完全是备用了。

2. 去新建一个Supabase项目,我们会在两处使用到:

• 数据库操作:我们会有相关的数据库存储操作。Agent会主动帮我们将我们的一个选题的标题插入到数据库里面去。

• Edge Function的使用:同时,我们会使用 Edge Function 去获取 B 站当天的实时热门数据。作为我们一个重要的后端接口的开发

3. 去下载Next.js + Drizzle模板:

• 去到官网下载 Next.js 和 Drizzle 的一个前端模板。我们这个模板会作为我们网站的前端部分。当然,您可以直接使用我的模板文件。

• 使用Cursor打开这个项目,把。env.example这个文件复制一份,修改成为 .env 的文件,然后将 Supabase 的数据库的URL 粘贴到环境变量的 POSTGRES_URL 当中。

• 输入pnpm dev跑起来我们这个项目,如果你看到下面的画面,就说明你的模板和数据库连接成功了。

4. 准备Claude Code

我们本期开发前端+后端N8N请求会使用 Claude Code。当然如果你没有 Claude Code,也可以直接使用 Cursor。

5. 准备OpenRouter

这次我们的模型会使用到 Gemini 2.5 Flash,因为这个的上下文需要要求很大。模型调用的服务商,我们通过 OpenRouter 的方式来去调用。

6. 准备Apifox

Apifox会作为我们接口调用的一个测试工具。这个在我们之前的课程当中也有讲,大家可以直接去下载使用。

3. 获取B站热门视频接口

这一步我们将使用 Supabase 的 Edge function 来开发一个能够实时获取B 站热门视频前500的接口。Supabase的Edge Function在我们的 Supabase 草节中没有提到,是因为在大部分情况下,直接使用 Next.js的API Router 其实就足够了。因为它的作用本质上就是后端的接口。

但是这一次我们来尝试使用一下使用Edge Function,他还是有很多的优势:比如说 Edge Function和你的 Supabase 部署在一起,能够很方便地去连接数据库。它连接数据库的延迟更低,同时呢,他非常适合写那些能够被多端复用的微业务逻辑代码。那么我们这次获取B站热门数据前 200 的接口,其实就非常适合用它来写。

3.1 初体验Edge Function

进入到Supabase的后台,点击 Edge Functions,然后轻键一个最简单的 function。点击部署,稍等片刻就能看到你的函数已经部署上线了。

进入到函数后,把这个JWT验证给关闭掉。然后复制端点的请求地址,在 ApiFox上尝试去请求该地址(注意:这是一个 POST 请求。)

新建快捷请求输入对应的参数,你会发现你的请求成功了。说明这个接口就已经部署上线了。看是不是使用 Subabase 的 Edge function 特别的方便呢?

3.2 分析B站热门数据

接下来,我们来分析B 站这个热门数据的接口形式:

1. 进入到B站的一个热门数据的排行页面。

2. 打开浏览器的控制台,然后点击到 Network。

3. 再刷新一下,你会发现这里有一个 https://api.bilibili.com/x/web-interface/popular?ps=20&pn=1 接口这个接口就是 B站的热门数据的接口。

友情提示

不是所有的接口都是能够这么去获取。这个接口是没有任何的用户登陆验证操作的,可以尝试打开一个无痕的浏览器,直接访问这个接口。小技巧:在无痕浏览器上,如果这是一个 GET 请求,并且没有任何的验证操作,那才能这么操作。

接下来,我们来分析这个接口。其实,它带有两个参数:一个是ps参数,对应的是当前页面所需要的请求的数据数量;另一个是pn参数,这个参数代表的是第几个页面。也就是说,如果ps为50,pn为1,那么这就是前50条数据。如果 pn为2,那就是从51到100条数据。

经过调试,其实我们知道他最多一次希望只能获取50条数据。那么,如果我们想获取前两百条数据的话,就要请求四次。

新手友情提示

这个接口是一个非常典型的分页逻辑的接口。基本上,所有具有分页的数据都会有这两个参数。一个是页码的参数。另一个是每页有多少条数据的参数。但是接口的名称需要根据不同的业务动态地调整,名字是不固定的。这个时候,大家需要灵活地去变通的查看。

3.3 开发并部署接

在下方输入以下的提示词,让 Cladue Code 来帮我们创建 Edge Function。

• 提示词

请你帮我编写一个 Supabase 的 edge function: bilibili-popular。这个接口需要去请求该接口:https://api.bilibili.com/x/web-interface/popular?ps=50&pn=1 .ps为50,代表请求的数量. pn代表当前页数. 需要注意的是, 我需要请求前200条数据,并且每一页的最大请求的数量最多为50,所以说你要同时4次该请求,然后返回给我200条的数据

那等Claude Code开发成功之后,大家可以尝试采用命令行实现部署,当然也可以像我们刚才的直接在 Subabase 的后台实现部署。为了方便,我们直接在后台粘贴代码的形式实现部署。

部署成功之后的话,大概你第一次请求会触发到反爬虫。因为咱们同时并发请求4个的话,很容易导致被限制。所以说,我们最好让AI来帮我们去添加一个几百毫秒的间隔, 这样的话就会好很多。然后复制那新改的代码,再次进行部署。这样的话,基本上就没什么问题了。

输入以下提示词:

现在会触发到一个反爬虫的一个消息 请你去增加一个几百毫秒的间隔 不要一次性同时请求四个接口

这是最终 AI帮我生成的代码,大家可以直接拿去复制粘贴使用。

supabase/functions/bilibili-popular/index.ts

/// <reference types="https://deno.land/x/types/react.d.ts" />
interface BilibiliVideo {
aid: number
bvid: string
cid: number
title: string
desc: string
duration: number
pic: string
pubdate: number
stat: {
view: number
danmaku: number
reply: number
favorite: number
coin: number
share: number
like: number
}
owner: {
mid: number
name: string
face: string
}
}
interface BilibiliResponse {
code: number
message: string
data: {
list: BilibiliVideo[]
}
}
const sleep = (ms: number): Promise<void> => {
return new Promise(resolve => setTimeout(resolve, ms))
}
Deno.serve(async (req: Request) => {
const { method } = req
if (method !== 'GET') {
return new Response('Method not allowed', { status: 405 })
}
try {
const fetchPage = async (page: number): Promise<BilibiliVideo[]> => {
const response = await fetch(
`https://api.bilibili.com/x/web-interface/popular?ps=50&pn=${page}`,
{
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Referer': 'https://www.bilibili.com/',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8'
}
}
)
if (!response.ok) {
throw new Error(`Failed to fetch page ${page}: ${response.status}`)
}
const data: BilibiliResponse = await response.json()
if (data.code !== 0) {
throw new Error(`Bilibili API error: ${data.message}`)
}
return data.data.list
}
const allVideos: BilibiliVideo[] = []
const pages = [1, 2, 3, 4]
for (const page of pages) {
try {
const videos = await fetchPage(page)
allVideos.push(...videos)
if (page < pages.length) {
await sleep(500)
}
} catch (error) {
console.error(`Error fetching page ${page}:`, error)
}
}
return new Response(
JSON.stringify({
success: true,
total: allVideos.length,
data: allVideos
}),
{
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Headers': 'Content-Type'
}
}
)
} catch (error) {
console.error('Error fetching Bilibili data:', error)
return new Response(
JSON.stringify({
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
}),
{
status: 500,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
}
)
}
})

4. N8N搭建Agent
那接下来我们来通过 N8N 去搭建我们这个产品的Agent。首先需要强调一下,大家一定要区分Agent和Workflow是有差别的。

我们之前在OOTD小程序当中有讲过Coze的工作流,你会发现Workflow是一一个固定的流程,基本上你输入什么,输出是什么,你的节点流程是一致的,是规划好的。

但是Agent和Workflow最大的区别就是,Agent的流程是不一致的。它会根据你所提供给它的一个工具调用来自主决定它的流程是如何的。

如果你的N8N免费使用到期了

• 我们这次实验使用 N8N的一个云端版本。大家可以去注册下载,有14天的一个免费的使用权限。学习这个课程完全足够了。

• 同时N8N是开源的,你可以自己本地下载然后进行部署的,你也可以去到我们课程中有讲过Zeabur,可以直接使用N8N模板部署。

4.1 创建Webhook触发器

当我们新创建一个工作流之后,我们需要去增加一个触发器。点击“Add first step” 会发现有很多可选择的触发器。最常用的,我们可以通过点击的方式手动触发,或者以定时的方式去触发。

1.创建Webhook节点

在这里,我们想把这个 agent 制作成一个通过 HTTP 调用的方式,这样我们就可以通过 webhook call 的方式去触发它。点击【on webhook call】

修改一下配置信息:

• HTTP Method: POST

• Path: chat

• Respond: Using ‘Respond to Webhook’ Node

2. 创建Respond to Webhook节点

• 在点击+号,创建一个【Respond to Webhook】节点,设置Respond with:ALL Incoming Items

3. 创建Edit Fields节点

• 在两个节点直接新建一个【Edit Fields】

• 新建一个测试JSON字段

• 保存一下最终效果

4. 测试

接下来,我们来测试一下这个 webhook 的工作流的正常调用。

  1. 点击第一个webhook节点,复制这个链接地址到ApiFox中