Haystack Firecrawl 集成实战:用 FirecrawlCrawler 与 FirecrawlWebSearch 构建网站抓取与联网检索管道
【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
本文聚焦 Haystack 官方参考文档中收录的 Firecrawl 集成(见 集成 API 参考),深入讲解其中两个核心组件:负责整站爬取的FirecrawlCrawler与负责联网搜索并抓取正文的FirecrawlWebSearch。读完本文,你将掌握这两个组件的完整 API 签名、参数语义、同步/异步调用方式,以及如何把它们接入索引管道与 RAG 管道,直接用 Firecrawl 返回的 Markdown 结构化内容喂给 LLM。
Firecrawl 集成概览
Firecrawl 是一项网页爬取与内容抽取服务,它能将网站页面转换为适合 LLM 消费的结构化格式(典型如 Markdown)。在 Haystack 中,Firecrawl 集成以firecrawl-haystack包的形式提供,包含两个组件,分别落在两类组件族中:
| 组件 | 归属类别 | 核心职责 |
|---|---|---|
FirecrawlCrawler | Fetchers(数据抓取) | 从一个或多个起始 URL 出发,沿链接爬取子页面,返回 HaystackDocument列表 |
FirecrawlWebSearch | WebSearch(联网搜索) | 封装 Firecrawl Search API,搜索网页并抓取结果正文,返回Document与links |
在 Fetchers 组件索引 中,FirecrawlCrawler与GoogleDriveFetcher、LinkContentFetcher、TavilyFetcher等并列,定位于"从 URL、网络爬虫或云存储获取外部内容";在 WebSearch 组件索引 中,FirecrawlWebSearch与BraveWebSearch、SerperDevWebSearch、TavilyWebSearch等并列,定位于"用组件在互联网上查找答案"。与普通搜索组件不同,Firecrawl 搜索返回的是经过抓取与结构化处理的页面正文,因此通常无需再串联LinkContentFetcher单独读取网页。
两个组件都要求持有 Firecrawl API key:默认读取FIRECRAWL_API_KEY环境变量,也可在初始化时显式传入。
安装
pip install firecrawl-haystack安装后即可从两个入口导入组件:
from haystack_integrations.components.fetchers.firecrawl import FirecrawlCrawler from haystack_integrations.components.websearch.firecrawl import FirecrawlWebSearch鉴权方式:Secret 与环境变量
Haystack 推荐用Secret对象管理 API key。Secret是 Haystack 核心工具(见 haystack/utils/init.py 中的导出),支持从环境变量解析密钥。两种等价写法:
from haystack.utils import Secret # 方式一:从环境变量读取(组件默认行为) api_key = Secret.from_env_var("FIRECRAWL_API_KEY") # 方式二:直接以字符串注入 api_key = Secret.from_token("<your-api-key>")FirecrawlCrawler(api_key=Secret.from_token("<your-api-key>"))是官方组件文档(FirecrawlCrawler 页面)给出的显式传参方式。API key 需要先在 Firecrawl 官网注册获取。
FirecrawlCrawler:整站爬取组件
FirecrawlCrawler从每个给定的起始 URL 开始爬取,沿页面链接发现子页面,直到达到可配置的上限。它适合摄入整个网站或文档站点,而不仅仅是单个页面——这是它与单页抓取器(如LinkContentFetcher)最本质的区别。
初始化参数
__init__( api_key: Secret = Secret.from_env_var("FIRECRAWL_API_KEY"), params: dict[str, Any] | None = None, ) -> Noneapi_key:Firecrawl 的 API key,默认从FIRECRAWL_API_KEY环境变量读取。params:爬取请求参数,透传给 Firecrawl 的 crawl 接口,完整参数列表见 Firecrawl API 文档。默认值为{"limit": 1, "scrape_options": {"formats": ["markdown"]}}。
crawl 请求参数(params)
官方组件文档列出的两个最常用参数:
| 参数 | 默认值 | 作用 |
|---|---|---|
limit | 1 | 每个 URL 最多爬取的页面数。若不设置 limit,Firecrawl 可能爬取全部子页面,快速消耗积分额度 |
scrape_options | {"formats": ["markdown"]} | 控制输出格式,Markdown 是适合 LLM 输入的结构化格式 |
例如限制每个起始 URL 只爬 5 个页面:
crawler = FirecrawlCrawler( api_key=Secret.from_env_var("FIRECRAWL_API_KEY"), params={"limit": 5}, )run 与 run_async
run(urls: list[str], params: dict[str, Any] | None = None) -> dict[str, Any] run_async( urls: list[str], params: dict[str, Any] | None = None ) -> dict[str, Any]urls:要爬取的 URL 列表。params:本次运行的爬取参数覆盖项。注意语义:如果传入,会完全替换初始化时的params,而不是合并。
返回值是一个字典,包含键:
documents:爬取得到的 Document 列表,每个被抓取的页面对应一个 Document。
warm_up 与 warm_up_async
warm_up() -> None warm_up_async() -> Nonewarm_up()用于预热同步 Firecrawl 客户端,warm_up_async()预热异步客户端。在管道中运行组件前调用 warm-up 可以避免首次调用的冷启动开销。
独立使用
参考文档给出的最小可用示例:
from haystack_integrations.components.fetchers.firecrawl import FirecrawlCrawler crawler = FirecrawlCrawler( api_key=Secret.from_env_var("FIRECRAWL_API_KEY"), params={"limit": 5}, ) crawler.warm_up() result = crawler.run(urls=["https://docs.haystack.deepset.ai/docs/intro"]) documents = result["documents"]更完整的写法是遍历结果,读取每个 Document 的元数据:
from haystack_integrations.components.fetchers.firecrawl import FirecrawlCrawler crawler = FirecrawlCrawler(params={"limit": 3}) result = crawler.run(urls=["https://docs.haystack.deepset.ai/docs/intro"]) documents = result["documents"] for doc in documents: print(f"{doc.meta.get('title')} - {doc.meta.get('url')}")输出结构:Document 的 content 与 meta
每个被抓取的页面成为一个独立的Document:页面正文放在content字段,标题(title)、URL(url)、描述(description)等元数据放在meta字段。这与 Haystack 核心 Document 数据类 的定义一致——content存放文档文本,meta存放必须可 JSON 序列化的附加元数据。因此在接入下游组件时,你可以直接通过doc.content获取可喂给 LLM 的正文,通过doc.meta回溯页面来源。
在索引管道中使用
官方组件文档给出了完整的索引管道示例:用FirecrawlCrawler爬取文档站点,经DocumentSplitter切分后写入InMemoryDocumentStore,构成"抓取 → 切分 → 写入"的标准摄入链路:
from haystack import Pipeline from haystack.document_stores.in_memory import InMemoryDocumentStore from haystack.components.preprocessors import DocumentSplitter from haystack.components.writers import DocumentWriter from haystack_integrations.components.fetchers.firecrawl import FirecrawlCrawler document_store = InMemoryDocumentStore() crawler = FirecrawlCrawler(params={"limit": 10}) splitter = DocumentSplitter(split_by="sentence", split_length=5) writer = DocumentWriter(document_store=document_store) indexing_pipeline = Pipeline() indexing_pipeline.add_component("crawler", crawler) indexing_pipeline.add_component("splitter", splitter) indexing_pipeline.add_component("writer", writer) indexing_pipeline.connect("crawler.documents", "splitter.documents") indexing_pipeline.connect("splitter.documents", "writer.documents") indexing_pipeline.run( data={ "crawler": { "urls": ["https://docs.haystack.deepset.ai/docs/intro"], }, }, )这里crawler.documents是FirecrawlCrawler的输出 socket,管道运行参数通过data字典按组件名传入起始 URL 列表。整套链路展示了如何把整站内容批量转成可检索的知识库。
FirecrawlWebSearch:联网搜索组件
FirecrawlWebSearch封装 Firecrawl 的 Search API:给定查询词后,它先搜索网页,再爬取结果页面,把结构化正文作为 HaystackDocument列表返回,同时返回底层 URL 列表。它遵循 Haystack 标准的 WebSearch 组件接口,可以和其他 WebSearch 组件互换使用。
初始化参数
__init__( api_key: Secret = Secret.from_env_var("FIRECRAWL_API_KEY"), top_k: int | None = 10, search_params: dict[str, Any] | None = None, ) -> Noneapi_key:Firecrawl API key,默认从FIRECRAWL_API_KEY环境变量读取。top_k:最多返回的 Document 数量,默认10。可被search_params中的"limit"参数覆盖。search_params:透传给 Firecrawl Search API 的附加参数,完整列表见 Firecrawl API 文档。官方参考文档明确列出的受支持键包括:tbs、location、scrape_options、sources、categories、timeout。
run 与 run_async
run(query: str, search_params: dict[str, Any] | None = None) -> dict[str, Any] run_async( query: str, search_params: dict[str, Any] | None = None ) -> dict[str, Any]query:搜索查询字符串。search_params:本次运行的搜索参数覆盖项,若传入则完全替换初始化时的search_params。
返回值是一个字典,包含两个键:
documents:包含搜索结果正文的 Document 列表。links:搜索结果对应的 URL 列表。
warm_up 与 warm_up_async
与FirecrawlCrawler一致,warm_up()预热同步客户端,warm_up_async()预热异步客户端。
独立使用
参考文档给出的最小示例:
from haystack_integrations.components.websearch.firecrawl import FirecrawlWebSearch from haystack.utils import Secret websearch = FirecrawlWebSearch( api_key=Secret.from_env_var("FIRECRAWL_API_KEY"), top_k=5, ) result = websearch.run(query="What is Haystack by deepset?") documents = result["documents"] links = result["links"]配合scrape_options指定 Markdown 格式并遍历正文的完整写法:
from haystack_integrations.components.websearch.firecrawl import FirecrawlWebSearch from haystack.utils import Secret web_search = FirecrawlWebSearch( api_key=Secret.from_env_var("FIRECRAWL_API_KEY"), top_k=5, search_params={"scrape_options": {"formats": ["markdown"]}}, ) query = "What is Haystack by deepset?" response = web_search.run(query=query) for doc in response["documents"]: print(doc.content)在 RAG 管道中使用
FirecrawlWebSearch的一个关键优势是:它返回的documents已是抓取并结构化后的页面正文,可以直接接入ChatPromptBuilder作为 LLM 的上下文,无需额外的抓取组件。官方组件文档(FirecrawlWebSearch 页面)给出了完整的 RAG 管道示例:
from haystack import Pipeline from haystack.utils import Secret from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder from haystack.components.generators.chat import OpenAIChatGenerator from haystack_integrations.components.websearch.firecrawl import FirecrawlWebSearch from haystack.dataclasses import ChatMessage web_search = FirecrawlWebSearch( api_key=Secret.from_env_var("FIRECRAWL_API_KEY"), top_k=2, search_params={"scrape_options": {"formats": ["markdown"]}}, ) prompt_template = [ ChatMessage.from_system("You are a helpful assistant."), ChatMessage.from_user( "Given the information below:\n" "{% for document in documents %}{{ document.content }}\n{% endfor %}\n" "Answer the following question: {{ query }}.\nAnswer:", ), ] prompt_builder = ChatPromptBuilder( template=prompt_template, required_variables={"query", "documents"}, ) llm = OpenAIChatGenerator( api_key=Secret.from_env_var("OPENAI_API_KEY"), model="gpt-5-nano", ) pipe = Pipeline() pipe.add_component("search", web_search) pipe.add_component("prompt_builder", prompt_builder) pipe.add_component("llm", llm) pipe.connect("search.documents", "prompt_builder.documents") pipe.connect("prompt_builder.prompt", "llm.messages") query = "What is Haystack by deepset?" result = pipe.run(data={"search": {"query": query}, "prompt_builder": {"query": query}}) print(result["llm"]["replies"][0].text)该管道的数据流为:FirecrawlWebSearch搜索并抓取正文 →ChatPromptBuilder把文档拼进模板生成 prompt →OpenAIChatGenerator基于上下文作答。由于FirecrawlWebSearch遵循标准 WebSearch 组件接口,它的documents输出也可以被ComponentTool(见 haystack/tools/component_tool.py)包装成 Agent 可调用的工具,让智能体自主执行联网检索。
同步与异步支持
两个组件都同时提供同步与异步两套接口,便于适配不同的执行场景:
| 组件 | 同步 | 异步 |
|---|---|---|
FirecrawlCrawler | warm_up()/run() | warm_up_async()/run_async() |
FirecrawlWebSearch | warm_up()/run() | warm_up_async()/run_async() |
同步接口适合在传统Pipeline中顺序执行;异步接口则适合高并发抓取/搜索场景,可以搭配 Haystack 的异步管道能力批量处理多个 URL 或查询。参考文档中两组接口的参数与返回值语义完全一致,异步版本只是执行模型不同。
最佳实践与注意事项
综合参考文档与组件文档,使用 Firecrawl 集成时有几点值得注意:
- 务必设置
limit控制爬取范围:FirecrawlCrawler的默认limit是1;如果不显式设置,Firecrawl 可能爬取所有子页面并快速消耗积分。建议按站点规模设置合理的limit,如{"limit": 5}或{"limit": 10}。 - 参数覆盖是"整体替换"而非合并:无论是
FirecrawlCrawler.run的params还是FirecrawlWebSearch.run的search_params,只要传入就会完全替换初始化时的参数。若只想微调,需在调用时重新给出完整参数集。 - 优先输出 Markdown:默认的
scrape_options={"formats": ["markdown"]}是最适合 LLM 消费的格式;搜索场景下同样建议在search_params中显式指定scrape_options。 - 用
Secret管理密钥:默认从FIRECRAWL_API_KEY环境变量读取,避免把密钥硬编码进代码或管道配置。 - 抓取后按需切分:爬取/搜索返回的页面正文可能很长,接入索引管道时建议像官方示例那样先用
DocumentSplitter切分再写入文档存储,以提升后续检索质量。
小结
Firecrawl 集成通过两个互补的组件,把"整站内容摄入"和"联网实时检索"两类高频需求接入 Haystack 管道:FirecrawlCrawler负责从起始 URL 出发深挖子页面,适合批量构建知识库;FirecrawlWebSearch负责搜索并直接返回结构化正文,适合 RAG 与 Agent 的实时联网查询。两者都以 Markdown 形式返回可直接喂给 LLM 的 Document,配合 Haystack 的Pipeline、DocumentSplitter、ChatPromptBuilder等核心组件即可快速落地生产级应用。更完整的组件用法可进一步阅读 FirecrawlCrawler 组件文档 与 FirecrawlWebSearch 组件文档,API 签名细节以 集成 API 参考 为准。
【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考