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

嘿,各位爬虫老战友、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 },
// ...
// ]
这段代码背后发生了什么?
client.robots.run()发起POST请求到/api/robots/airbnb-property-extractor/run,携带参数和签名api-server校验API Key权限,查出该Robot的定义(包括录制轨迹、AI提示词模板、重试策略、超时阈值)- 将任务推入Redis队列,由
playwright-worker消费 - Worker启动Chromium实例,创建
browserContext,注入预设的登录Cookie(如果Robot配置了login flow) - 执行录制动作:
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') - 提取阶段:若为AI Mode,调用LLM服务生成提取逻辑;若为Recorder Mode,则执行预存的
page.locator('.listing-card').all()+map()结构化 - 结果序列化为JSON,写入Redis,通知客户端轮询或通过WebSocket推送
实战演示:5分钟搞定招聘网站职位抓取
假设你要监控BOSS直聘的「Java架构师」岗位变动:
- 启动Maxun:
docker-compose up -d,访问https://localhost:3000 - 点击「Create Robot」→ 选择「Record Mode」→ 输入URL
https://www.zhipin.com/beijing/?query=Java+%E6%9E%B6%E6%9E%84%E5%B8%88 - 在浏览器里:点击筛选「经验5-10年」→ 点击「排序:最新发布」→ 滚动到底部触发分页 → 右键选中第一个职位卡片 → 「Extract as JSON」→ 命名为
boss-java-architect - 保存Robot,点击「Run Now」,看到实时返回10条结构化数据
- 复制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解析器的世界,到底长啥样 😎)