Maxun:把网站变成API的AI数据机器人

96 次阅读 0 点赞 0 评论 10 分钟原创开源项目

Maxun是GitHub Trending榜首的开源项目,用TypeScript+Playwright构建,支持无代码录制与LLM驱动的数据提取。它将网页转化为REST API,内置DOM指纹比对、登录态保持、自适应结构变更能力,并提供SDK供Spring Boot等后端集成。AGPLv3协议需注意商用风险。

#web-scraping #ai-extraction #no-code #playwright #structured-data #typescript
Maxun:把网站变成API的AI数据机器人

嘿,各位爬虫老战友、AI数据搬运工、还有被反爬封到怀疑人生的Java后端兄弟们——我是周小码,一个被Spring AOP织入太多切面、差点把自己也代理成Bean的8年老兵。今天不聊@Transactional失效的深夜debug故事,来盘一盘这个刚杀上GitHub Trending榜首的狠角色:Maxun

痛点引入:你写的XPath,活不过下个版本迭代

还记得那个凌晨三点的电话吗?“周哥,京东商品页改版了,价格字段从<span class="price">挪到了<div data-testid="final-price">,XPath全挂,订单同步断了两小时……”

这不是个例。电商详情页加个「拼团倒计时」模块,XPath崩;政府公告站换套Vue3主题,Jsoup解析器吐异常;竞品爬虫跑着跑着突然返回403,连User-Agent都没动过——因为对方加了Cloudflare的JS挑战,而你的headless Chrome没加载完challenge脚本就超时退出。

更糟的是:这些逻辑散落在几十个Python脚本里,没人敢动,没人敢删,没人敢写单元测试。它们像《清明上河图》里的漕运船队——表面井然有序,实则靠老师傅手绘航线图和口头传承维持运转。

解决方案:不是写爬虫,是编排机器人

Maxun的解法很干脆:把爬虫抽象成Robot,把提取逻辑封装成指令,把适配变更交给底层引擎

它不让你写一行XPath或CSS选择器,而是提供两种模式:

  • Recorder Mode(录制模式):你在浏览器里点、填、翻页、右键复制表格,Maxun全程录制为可重放的“操作轨迹”。背后不是简单录HTTP请求,而是基于Playwright的page.click()page.fill()page.waitForSelector()等真实浏览器行为,连动态加载的React懒加载组件都能等稳。

  • AI Mode(大模型驱动提取):你输入自然语言:“请从IMDb首页提取Top 50电影的片名、评分、时长,并按评分倒序”。LLM(本地或远程)理解语义后,生成并执行DOM定位策略——不是硬编码selector,而是先做结构分析(如“评分在class含‘rating’的span内,且紧邻h3标签”),再结合XPath弹性回退机制匹配。若主路径失效,自动降级到备用路径(比如从//div[@class='lister-item']切到//article[contains(@class,'lister-item')])。

这已经不是自动化,这是在给网页装上「语义理解大脑」。

核心代码解析:看它怎么把网站变成API

Maxun的后端暴露标准REST接口,核心是POST /api/robots/{id}/run。我们来看它的调用链路如何落地:

bash 复制代码
## 本地安装(Docker Compose方式)
git clone https://github.com/getmaxun/maxun.git
cd maxun
docker-compose up -d

这段命令启动的是一个完整的全栈服务:

  • nginx作为反向代理,处理HTTPS和静态资源
  • api-server(Node.js + Express)负责路由、认证、Robot调度
  • playwright-worker(独立进程)承载真实浏览器实例,每个Robot运行在隔离的browserContext中,保证登录态、localStorage、cookie互不干扰
  • redis用于任务队列和状态存储(Robot生命周期管理、重试计数、失败快照)

关键不在启动,而在调用:

typescript 复制代码
// 通过SDK调用Extract Robot(伪代码示意,基于其Node SDK文档推演)
import { MaxunClient } from '@maxun/sdk';

const client = new MaxunClient({
  baseUrl: 'http://localhost:3000',
  apiKey: 'your-api-key' // 基于JWT的RBAC权限控制
});

// 运行已配置好的Extract Robot
const result = await client.robots.run('airbnb-property-extractor', {
  params: {
    location: 'Tokyo',
    checkIn: '2026-03-01',
    maxResults: 10
  }
});

console.log(result.data); // 返回结构化JSON数组
// [
//   { "title": "Shibuya Loft Apartment", "price": "$89/night", "rating": 4.92 },
//   ...
// ]

这段代码背后发生了什么?

  1. client.robots.run() 发起POST请求到/api/robots/airbnb-property-extractor/run,携带参数和签名
  2. api-server校验API Key权限,查出该Robot的定义(包括录制轨迹、AI提示词模板、重试策略、超时阈值)
  3. 将任务推入Redis队列,由playwright-worker消费
  4. Worker启动Chromium实例,创建browserContext,注入预设的登录Cookie(如果Robot配置了login flow)
  5. 执行录制动作:page.goto('https://www.airbnb.com/s/Tokyo--Japan')page.fill('[aria-label="Check in"]', '2026-03-01')page.click('button:has-text("Search")')page.waitForSelector('.listing-card')
  6. 提取阶段:若为AI Mode,调用LLM服务生成提取逻辑;若为Recorder Mode,则执行预存的page.locator('.listing-card').all() + map()结构化
  7. 结果序列化为JSON,写入Redis,通知客户端轮询或通过WebSocket推送

实战演示:5分钟搞定招聘网站职位抓取

假设你要监控BOSS直聘的「Java架构师」岗位变动:

  1. 启动Maxun:docker-compose up -d,访问 https://localhost:3000
  2. 点击「Create Robot」→ 选择「Record Mode」→ 输入URL https://www.zhipin.com/beijing/?query=Java+%E6%9E%B6%E6%9E%84%E5%B8%88
  3. 在浏览器里:点击筛选「经验5-10年」→ 点击「排序:最新发布」→ 滚动到底部触发分页 → 右键选中第一个职位卡片 → 「Extract as JSON」→ 命名为boss-java-architect
  4. 保存Robot,点击「Run Now」,看到实时返回10条结构化数据
  5. 复制Robot ID,在你的Spring Boot服务里写个定时任务:
java 复制代码
// Spring Boot中封装MaxunClient(非官方,但极简)
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点
public void fetchBossJobs() {
    String json = restTemplate.postForObject(
        "http://localhost:3000/api/robots/boss-java-architect/run",
        Map.of("params", Map.of("city", "beijing")),
        String.class
    );
    List<Job> jobs = objectMapper.readValue(json, new TypeReference<>() {});
    jobRepository.saveAll(jobs);
}

零行爬虫代码,零维护XPath,只有业务逻辑。

踩坑指南:别掉进这几个深坑

  • 内存吃紧:Playwright默认启动Chromium,单个worker常驻内存300MB+。建议生产环境用--single-process或限制maxWorkers: 2,避免OOM。
  • AGPLv3传染性:如果你基于Maxun二次开发并提供SaaS服务,必须开源修改部分。想闭源?得买商业授权,或自己fork后移除AGPL依赖(比如换掉playwright-core为轻量级Puppeteer fork)。
  • AI Mode延迟高:LLM调用默认走OpenRouter,首字节延迟常超2s。README明确建议:对SLA敏感场景,优先用Recorder Mode;AI Mode仅作兜底或探索性分析。
  • 登录态失效:某些网站(如知乎)会检测navigator.webdriver。Maxun在playwright-worker中已打patch:await page.addInitScript(() => { Object.defineProperty(navigator, 'webdriver', { get: () => false }); });,但复杂风控(如极验)仍需人工介入。

个人评价:它不卷Java,但它在重新定义边界

作为写了8年Java的老兵,我第一反应是:“缺个Spring Boot Starter,缺Actuator端点,缺Prometheus Metrics”。但转念一想——它压根不打算卷Java生态。它瞄准的是No-Code+AI原生用户:运营同学能自己搭Robot,数据分析师能用自然语言提需求,前端用@maxun/sdk三行代码接入外部数据源。

它的真正价值,不是替代你写Jsoup,而是逼你思考:当“写爬虫”不再是技术门槛,后端工程师的核心竞争力,是不是该从“怎么取数据”,升级为“怎么定义数据契约、怎么设计数据流拓扑、怎么保障数据血缘可信”?

Maxun没写一行Java,但它正在重新定义‘后端数据接入’这件事的边界。

(P.S. 如果你真在生产环境用了它,记得给我发个截图——我想看看那个让我不用再写Jsoup解析器的世界,到底长啥样 😎)

最后更新:2026-02-14T10:01:41

评论 (0)

发表评论

blog.comments.form.loading
0/500
加载评论中...