模型 / 数据集
mishushakov/llm-scraper avatar
mishushakov/llm-scraper

llm-scraper:用 LLM 把网页变成结构化数据,但先想清楚成本

Turn any webpage into structured data using LLMs

6,927 个 Star453 个 ForkTypeScriptMIT
GitHub

秒懂

它是什么?
llm-scraper 是一个 TypeScript 库,借助 Playwright 和 Vercel AI SDK,让 LLM 从任意网页提取符合 Zod 或 JSON Schema 的结构化数据。它灵活,但每次调用都烧 token,且依赖外部模型,适合原型验证而非大规模爬虫。
适合谁用?
llm-scraper 适合需要快速从动态网页提取少量、结构灵活数据的开发者,比如做原型、内部工具或小规模数据采集。它不适合需要高吞吐、低成本或完全离线运行的场景。
能商用吗?
可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
还在维护吗?
在维护。仓库最近一次提交在 6 天前。
用什么语言写的?
主要是 TypeScript(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。

开源项目深度解析

它解决什么问题,以及谁需要它

传统爬虫的痛点在于,网页结构一变,选择器就失效,你得重写解析逻辑。llm-scraper 的思路是跳过 CSS 选择器,让 LLM 直接阅读页面内容,再按你定义的 schema 输出 JSON。它面向的是这样一类人:需要从大量不同来源的网页里抽取特定字段,但每个页面的 DOM 结构差异太大,不值得为每个站点写定制解析器。典型场景包括聚合新闻标题、抓取商品信息、整理联系资料。它不是一个通用爬虫框架,而是一个把 Playwright 页面内容喂给 LLM 的封装层。你仍然需要自己处理页面导航、翻页、反爬等底层问题,llm-scraper 只负责最后一步,即从已加载的页面中提取结构化数据。

核心机制:从页面到 schema 的流水线

llm-scraper 的工作流程可以拆成四步。第一步,你用 Playwright 打开页面,拿到 page 对象。第二步,你定义一个 Zod schema,描述你想提取的数据结构,比如数组长度、字段类型。第三步,调用 scraper.run(page, Output.object({ schema }), { format: 'html' }),库内部会把页面内容按指定格式预处理,然后连同 schema 一起发送给 LLM。第四步,LLM 返回 JSON,库帮你解析并校验。关键在于 format 参数,它决定了 LLM 看到的是什么。html 模式会先预处理页面,去掉脚本和样式,只留结构;raw_html 则原样发送,内容可能很大,token 消耗也高;markdown 和 text 模式分别转换页面为 Markdown 或纯文本,text 模式还用了 Mozilla 的 Readability.js 来提取正文;image 模式则直接截图,要求模型支持多模态,比如 GPT-4o 或 Claude;custom 模式让你传入自定义函数处理页面。这个设计让你可以根据页面类型和模型能力,在 token 成本和提取准确率之间做权衡。

上手:三条命令加一个 schema

安装很简单,README 里给出了明确的步骤。你先装基础依赖 npm i zod playwright llm-scraper,再按你选的模型提供商装对应的适配器包,比如 @ai-sdk/openai 或 @ai-sdk/anthropic。然后初始化模型实例,llm-scraper 依赖 Vercel AI SDK 6,所以模型对象必须符合 AI SDK 的接口。以 OpenAI 为例,代码是 const llm = openai('gpt-4o')。接着创建 scraper 实例 new LLMScraper(llm)。最后调用 run 方法,传入 Playwright 的 page 对象和 schema。README 里的 HackerNews 示例展示了完整流程:定义 schema 为包含 top 数组的对象,数组元素有 title、points、by、commentsURL 四个字段,然后用 .length(5) 限制只取前五条。输出是一个符合 schema 的 JavaScript 对象。如果你想边生成边看结果,可以用 stream 方法替代 run,它返回一个异步迭代器,能流式输出部分对象。这种设计对长结果的体验更友好,但要注意,流式模式下你收到的每个片段可能都不完整。

代码生成:一条看似省钱的捷径

llm-scraper 提供了一个 generate 函数,它不直接调用 LLM 提取数据,而是让 LLM 生成一段可复用的 Playwright 脚本,这段脚本在页面上执行后,能直接返回符合 schema 的数据。用法是 const { code } = await scraper.generate(page, Output.object({ schema })),然后 const result = await page.evaluate(code),再用 schema.parse(result) 校验。这个功能的价值在于,一次生成后,后续抓取同一类页面就不需要再调用 LLM 了,只跑普通 JavaScript 即可,能大幅降低 token 成本。但代价是,生成的代码是针对当前页面结构写死的,如果目标网站改版,这段代码就会失效,你又得重新调用 generate。所以它适合页面结构相对稳定的场景,不适合频繁变动的站点。README 没有说明生成代码的质量如何,也没提是否保证可执行,实际效果取决于模型的推理能力和页面的复杂程度。

明确的局限:成本、延迟和不确定性

llm-scraper 最明显的局限是每次提取都是一次 LLM 调用,这意味着成本与页面大小、schema 复杂度直接挂钩。html 模式虽然预处理过,但一个大型页面可能仍有数千 token,按 GPT-4o 的定价,抓一千个页面不是小数目。延迟也是问题,LLM 生成 JSON 需要几秒到十几秒,远慢于传统选择器。更关键的是不确定性,LLM 可能漏字段、输出格式错误,或者理解偏差,schema 校验只能发现格式问题,不能保证语义正确。README 没有提到任何重试机制或错误处理策略,这意味着你需要自己处理解析失败的情况。另外,image 格式依赖多模态模型,不是所有模型都支持,README 列出的 Ollama 本地模型比如 llama3 就不一定支持。如果你要抓取的是登录后才能看到的页面,llm-scraper 本身不处理认证,你得先用 Playwright 手动处理登录状态。

替代方案:传统选择器与专用提取库

如果页面结构固定,且数据量巨大,传统方法仍然更高效。用 Playwright 的 locator 或 Cheerio 配合 CSS 选择器,一次请求就能拿到所有数据,成本几乎为零,速度是毫秒级。缺点是维护成本高,页面一变就要改代码。另一个思路是使用专门的网页提取库,比如 Mozilla 的 Readability.js,它能把网页正文转成干净的文本或 Markdown,但只适合提取文章内容,无法按任意 schema 输出结构化字段。还有像 Apify 的爬虫模板,它们提供预构建的提取逻辑,但定制能力有限。llm-scraper 的独特之处在于它把 schema 驱动和 LLM 语义理解结合起来,这让它能处理那些没有明显 DOM 模式可循的页面,比如动态渲染的内容或用自然语言描述需求的任务。但你应该清楚,这种灵活性的代价是每次调用都花钱。

维护与升级:依赖链和版本风险

llm-scraper 的 README 明确提到 2.0 版本升级到了 Vercel AI SDK 6,这说明它紧跟 AI SDK 的迭代。但这也意味着你的项目必须同步升级 AI SDK 相关依赖,否则可能不兼容。它依赖 Playwright,这意味着你需要维护浏览器二进制文件,在 CI 或服务器环境里要额外安装。许可证是 MIT,你可以自由使用和修改,没有传染性义务。仓库里没有列出任何发布版本,最近一次推送是 2026 年 9 月,说明项目仍在活跃维护,但也没有提供变更日志或发布说明,你升级时得自己看 commit 历史。如果你在生产环境使用,建议锁定依赖版本,并定期检查上游更新。

编辑结论

llm-scraper 适合需要快速从动态网页提取少量、结构灵活数据的开发者,比如做原型、内部工具或小规模数据采集。它不适合需要高吞吐、低成本或完全离线运行的场景。若你打算采用,先验证三件事:所选模型在目标页面上的输出稳定性,token 成本是否符合预算,以及 Playwright 浏览器环境能否在你的部署平台运行。另外,代码生成功能生成的是 Playwright 脚本,不要指望它像 LLM 调用一样能自适应页面变化。最终判断:llm-scraper 的价值在于把 LLM 的语义理解能力封装成简洁的 API,但它的经济性和可靠性完全取决于你选的模型和页面复杂度,这不是一个开箱即用的生产级爬虫框架。

官方来源

  1. Issues
  2. License: MIT
  3. mishushakov/llm-scraper on GitHub
  4. README
社区笔记

社区笔记