Generator 本身不直接抓取网页,而是通过 yield Promise 实现异步抓取流程的可控暂停与恢复,适用于分页、限速、错误重试等场景,需配合 for await...of 或手动 next() 调度,且不解决 CORS 等网络限制问题。

Generator 本身不直接抓取网页,但它能帮你把异步抓取任务拆成可控的、可暂停的步骤,尤其适合需要分页、限速、错误重试或人工干预的场景。
用 Generator 管理抓取流程的节奏
传统 fetch 链式调用容易堆叠 Promise,而 Generator 可以把“发请求 → 等响应 → 解析 → 下一页”这些动作变成一个个可中断的步骤。你控制什么时候走下一步,而不是全靠回调或 await 埋点。
- 每次 yield 一个 Promise(比如 fetch 请求),外部调用 next() 触发下一次抓取
- 配合 async/await 使用:用 for await...of 遍历 Generator,自动等待每个 yield 出来的 Promise 完成
- 遇到错误时,可以 throw 到 Generator 内部,做针对性重试或跳过
分页抓取的典型结构
比如抓取某网站 1–5 页列表,每页 20 条:
function* crawlPages(maxPage = 5) {
for (let page = 1; page <= maxPage; page++) {
const url = `https://api.example.com/list?page=${page}`;
// yield fetch,让外部决定何时执行
yield fetch(url).then(r => r.json());
}
}
<p>// 使用时可逐页控制
async function run() {
const gen = crawlPages(5);
for await (const data of gen) {
console.log('got page data:', data.items.length);
// 这里可加延时、校验、保存逻辑
await new Promise(r => setTimeout(r, 1000)); // 限速
}
}结合状态与条件跳转
Generator 内部可以维护状态,根据响应结果决定是否继续、重试或终止:
立即学习“Java免费学习笔记(深入)”;
- yield 后接收外部传入的值(通过 next(value)),比如传入上次抓取是否成功
- 用 if / switch 控制流程分支,例如:失败则 yield null 并重试,成功则 yield 下一页 URL
- 避免无限循环:设置最大重试次数、超时标记或手动 break
注意实际限制和替代建议
浏览器环境不能直接跨域抓取第三方网页(CORS 限制),Generator 解决的是流程控制问题,不是跨域问题:
- 真实抓取需后端代理,或使用支持 CORS 的公开 API
- 若在 Node.js 环境(如 Puppeteer 或 axios),Generator 控制效果更明显
- 现代写法中,async generator(function* async)更自然,for await...of 是推荐搭配
不复杂但容易忽略:Generator 不是魔法,它把“怎么做”交给开发者调度;真正起作用的是你如何设计 yield 的粒度和响应处理逻辑。


















