作者:张大鹏 | 大鹏AI教育
标签:
AI爬虫CrawleeStagehand浏览器自动化
阅读提示
列表页上的 「Load More / 加载更多」 是动态爬虫的经典噩梦:
- 按钮 class 名随前端改版变化
- 点击后要等 XHR,条目数不固定
- 翻到底没有明确「最后一页」信号
传统 Playwright 脚本靠 CSS 选择器硬写,维护成本高。Crawlee 在 v3.16 起引入 StagehandCrawler:在 Crawlee 的请求队列、重试、存储体系上,叠加 Stagehand 的自然语言浏览器操作——你可以用一句话描述「点击加载更多,直到没有更多按钮」,而不是死磕 .btn-load-more-v2。
这篇面向合规采集:公开列表、授权后台、压测环境。不涉及绕过验证码、登录墙或反爬。
1. StagehandCrawler 在 Crawlee 栈里的位置
Crawlee 本身解决的是工程问题:
- RequestQueue / Dataset 持久化
- 自动重试、会话、代理钩子
- Playwright / Puppeteer 统一入口
Stagehand 解决的是交互表达问题:用自然语言描述「点哪个、填什么、等到什么出现」。
合在一起,典型链路是:
Seed URL → StagehandCrawler 打开页
→ act("click Load More until gone")
→ extract 列表字段入 Dataset
→ enqueue 详情页(可选)
边界:NL 操作不是免维护。页面结构大变时,指令语义可能失效,仍需监控失败率并回退到 getByRole 等显式 locator。
2. 最小示例:自然语言点 Load More
安装(版本号以项目为准):
npm i crawlee @crawlee/playwright stagehand
核心爬虫骨架:
import { StagehandCrawler } from '@crawlee/playwright';
import { Dataset } from 'crawlee';
const crawler = new StagehandCrawler({
maxRequestsPerCrawl: 50,
launchContext: {
launchOptions: { headless: true },
},
async requestHandler({ page, request, stagehand, log }) {
await page.goto(request.url, { waitUntil: 'domcontentloaded' });
// 自然语言:反复点「加载更多」,直到按钮消失或不可点
await stagehand.act(
'If there is a "Load More" or "加载更多" button, click it and wait for new list items. Repeat until the button is gone or disabled. Do not click more than 10 times.'
);
const items = await stagehand.extract({
instruction: 'Extract all article cards: title, url, summary if visible.',
schema: {
type: 'object',
properties: {
items: {
type: 'array',
items: {
type: 'object',
properties: {
title: { type: 'string' },
url: { type: 'string' },
summary: { type: 'string' },
},
required: ['title', 'url'],
},
},
},
required: ['items'],
},
});
await Dataset.pushData(items.items);
log.info(`Saved ${items.items.length} items from ${request.url}`);
},
});
await crawler.run(['https://example.com/articles']);
要点:
act要写清停止条件(最多点 10 次),防止无限循环extract必须绑 JSON Schema,避免幻觉字段- Crawlee 的
maxRequestsPerCrawl控制规模,配合限速
3. 工程化:队列、重试与观测
Load More 场景建议再加:
import { Configuration } from 'crawlee';
Configuration.getGlobalConfig().getEventManager().on('migrating', () => {
// 进程迁移时的钩子
});
const crawler = new StagehandCrawler({
maxRequestRetries: 2,
requestHandlerTimeoutSecs: 120,
minConcurrency: 1,
maxConcurrency: 2, // 公开站别拉太高
failedRequestHandler({ request, error }) {
console.error(`Failed ${request.url}:`, error);
// 留截图、HTML 片段供人工复盘
},
// ... requestHandler 同上
});
和纯 Playwright 脚本对比:
| 项 | 手写 Playwright | StagehandCrawler |
|---|---|---|
| Load More 交互 | 手写 loop + selector | NL act + 停止条件 |
| 持久化 | 自建 | Dataset / Queue 内置 |
| 失败重试 | 自建 | Crawlee 内置 |
| 合规限速 | 需自写 | 配合 concurrency + sleep |
| 可预测性 | 高(selector 明确) | 中(需 Schema + 监控) |
4. 合规边界
Stagehand 的「自然语言点按钮」不等于可以点「绕过验证」「同意所有 Cookie 后强行登录」这类违规操作。
| 允许 | 禁止 |
|---|---|
| 公开列表 Load More | 未授权登录后采数据 |
| 遵守 robots.txt | 破解验证码 / 滑块 |
| 低速、低并发 | 分布式压测式抓取 |
| 结构化公开字段 | 采用户私信、手机号等 |
遇到以下情况应停止任务并告警,而非让 Stagehand「想办法」:
- HTTP 403 / 429 持续出现
- 出现 CAPTCHA / 人机验证
- Terms 明确禁止 automated access
5. 上线检查清单
act是否写清 最大点击次数 与停止条件extract是否绑定了 JSON Schema- Crawlee
maxConcurrency是否控制在合理范围 - 是否有
failedRequestHandler留证 - 目标站是否公开或已授权
- 是否尊重 robots.txt
- 遇验证码是否停止而非绕过
- 首批数据是否人工对照页面抽检
6. 结论
Crawlee StagehandCrawler 适合 「列表 + Load More + 字段抽取」 这类交互重复、选择器易变的合规场景。推荐组合:
Crawlee 管队列与重试,Stagehand 管 NL 交互,Schema 管输出,人工管抽检与合规。
别把它当成反爬神器;把它当成降低 selector 维护成本的工程组件,价值才可持续。
参考来源
作者:张大鹏|来源:大鹏AI教育
标签:AI · 爬虫 · Crawlee · Stagehand
原创内容,转载需授权

























