用Firecrawl构建AI驱动的网络爬虫,感觉又刑了!
本文中,云朵君将和大家一起学习Firecrawl ,其通过一条命令抓取整个网站,并将其转化为 LLM 就绪的数据。Firecrawl是一款专为AI/ML应用设计的现代化网络爬虫工具,由Mendable.ai开发,核心功能是通过API将网页内容转换为LLM(大语言模型)友好的结构化数据(如Markdown、JSON),支持全站爬取、动态内容处理及多格式输出。
Firecrawl 最强大的功能-- /crawl端点,它可以实现大规模的自动化网站搜索。
递归遍历网站子页面 处理基于 JavaScript 的动态内容 绕过常见的网站抓取拦截器 为 AI/ML 应用程序提取干净的结构化数据
Web Scraping vs Web Crawling
Web scraping即网络抓取是指从维基百科文章或技术教程等单个网页中提取特定数据。它主要用于需要从具有已知网址的网页中获取特定信息的情况。
Web crawling既网络爬虫 则是指通过跟踪链接系统地浏览和发现网页。它侧重于网站导航和 URL 发现。
例如,要构建一个聊天机器人来回答有关 Stripe 文档的问题,你需要
网络爬虫,以发现和遍历 Stripe 文档网站中的所有页面 网络抓取,从每个发现的页面中提取实际内容
Firecrawl如何将两者结合起来
Firecrawl的/crawl端点结合了两种功能:
URL 分析: 通过网站导航或页面遍历识别链接 递归遍历: 跟踪链接以发现子页面 内容抓取: 从每个页面提取干净的内容 结果汇编: 将所有内容转换为结构化数据
当你将 URL https://docs.stripe.com/api 传递给端点时,它会自动发现并抓取所有文档子页面。端点会以你喜欢的格式返回内容--无论是 markdown、HTML、屏幕截图、链接还是元数据。
Firecrawl的核心功能
智能全站爬取
无需站点地图即可递归抓取网站所有子页面,支持深度控制和URL过滤(如限制爬取 /blog/*路径)。结合爬虫(Crawl)与抓取(Scrape)功能,既能发现链接,又能提取页面正文内容,自动去除广告、导航栏等噪音。
动态内容处理
支持渲染JavaScript生成的页面(如React/Vue应用),适用于现代动态网站。 通过无头浏览器和代理托管解决反爬机制(如速率限制、CAPTCHA)。
多格式输出
提供Markdown、HTML、JSON等格式,优化后的Markdown保留核心内容,适合直接输入LLM训练或RAG(检索增强生成)。 新增LLM Extract功能,通过大模型按预设Schema(如提取公司使命、产品特性)结构化数据。
高度可扩展性
提供Python、Node.js等SDK,集成LangChain、LlamaIndex等AI框架。 支持本地部署(需Redis、Node.js环境)或云端API调用,Scale计划支持百万级页面抓取。
使用 Firecrawl API 进行网络抓取
Firecrawl 是一个以 REST API 形式公开的网络抓取引擎。你可以通过命令行使用 cURL,也可以使用它的 Python、Node、Go 或 Rust 语言 SDK。在本文中,云朵君将和大家一起重点学习其 Python SDK。
开始使用
在 firecrawl.dev:https://firecrawl.dev/ 上注册,并复制你的 API 密钥 将密钥保存为环境变量:
export FIRECRAWL_API_KEY='fc-YOUR-KEY-HERE'
或者使用 dot-env 文件:
touch .env
echo"FIRECRAWL_API_KEY='fc-YOUR-KEY-HERE'" >> .env
然后使用 Python SDK:
from firecrawl import FirecrawlApp
from dotenv import load_dotenv
load_dotenv()
app = FirecrawlApp()
加载 API 密钥后,“FirecrawlApp ”类将使用该密钥与 Firecrawl API 引擎建立连接。
首先,我们将抓取 https://books.toscrape.com/ 网站,该网站是为网络抓取实践而构建的:
Firecrawl的 crawl_url 端点可让你在一行代码中完成上述工作,而无需使用 beautifulsoup4 或 lxml 等库编写几十行代码来解析HTML元素、处理分页和数据检索:
base_url = "https://books.toscrape.com/"
crawl_result = app.crawl_url(url=base_url)
结果是一个包含以下键的字典:
crawl_result.keys()
dict_keys(['success', 'status', 'completed', 'total', 'creditsUsed', 'expiresAt', 'data'])
首先,我们关注的是抓取任务的状态:
crawl_result['status']
'completed'
如果已完成,看看扫描了多少页:
crawl_result['total']
1195
将近 1200 页(在我的机器上耗时约 70 秒;速度因连接速度而异)。来看看"data"列表中的一个元素:
sample_page = crawl_result['data'][10]
markdown_content = sample_page['markdown']
print(markdown_content[:500])
- [Home](../../../../index.html "Home")
- [Books](../../books_1/index.html "Books")
- Womens Fiction
# Womens Fiction
**17** results.
**Warning!** This is a demo website for web scraping purposes. Prices and ratings here were randomly assigned and have no real meaning.
01. [](../../../i-had-a-nice-time-and-other-lies-how-to-find-love-sht-like-that_814/index.html)
该页面与Womens Fiction页面相对应:
Firecrawl 还会在元素字典中加入页面元数据metadata:
sample_page['metadata']
{
'url': 'https://books.toscrape.com/catalogue/category/books/womens-fiction_9/index.html',
'title': 'Womens Fiction | Books to Scrape - Sandbox',
'robots': 'NOARCHIVE,NOCACHE',
'created': '24th Jun 2016 09:29',
'language': 'en-us',
'viewport': 'width=device-width',
'sourceURL': 'https://books.toscrape.com/catalogue/category/books/womens-fiction_9/index.html',
'statusCode': 200,
'description': '',
'ogLocaleAlternate': []
}
有一件事我们没有提到,那就是 Firecrawl 是如何处理分页的。如果你滚动到Books-to-Scrape事部,就会看到它有一个next step 按钮。
在进入子页面(如 books.toscrape.com/category)之前,Firecrawl 会首先从主页抓取所有子页面。之后,如果子页面包含指向已抓取页面的链接,这些链接将被忽略。
高级网络抓取配置
Firecrawl提供多种类型的参数来配置端点抓取网站。下面我们一起看看这些参数及其使用案例。
抓取选项
在现实世界的项目中,你会最频繁地调整这个参数。它允许你控制网页内容的保存方式。Firecrawl 允许以下格式
Markdown- 默认格式HTML原始 HTML(整个网页的简单复制/粘贴)链接 links屏幕截图 screenshot
以下是一个请求以四种格式抓取 Stripe API 的示例:
# Crawl the first 5 pages of the stripe API documentation
stripe_crawl_result = app.crawl_url(
url="https://docs.stripe.com/api",
params={
"limit": 5, # Only scrape the first 5 pages including the base-url
"scrapeOptions": {
"formats": ["markdown", "html", "links", "screenshot"]
}
}
)
如果指定了多种格式,每个网页的数据都会为每种格式的内容包含单独的键:
stripe_crawl_result['data'][0].keys()
dict_keys(['html', 'links', 'markdown', 'metadata', 'screenshot'])
screenshot 键的值是一个指向存储在 Firecrawl 服务器上的 PNG 文件的临时链接,24 小时内过期。以下是 Stripe API 文档主页的样子:
from IPython.display import Image
Image(stripe_crawl_result['data'][0]['screenshot'])
请注意,指定更多格式来转换页面内容会大大降低处理速度。
另一个耗时的操作是抓取整个网页内容,而不是只抓取你想要的元素。针对这种情况,Firecrawl 可以使用onlyMainContent、includeTags和 excludeTags 参数来控制刮取网页中的哪些元素。
启用onlyMainContent参数(默认情况下禁用)将不包括导航、页眉和页脚:
stripe_crawl_result = app.crawl_url(
url="https://docs.stripe.com/api",
params={
"limit": 5,
"scrapeOptions": {
"formats": ["markdown", "html"],
"onlyMainContent": True,
},
},
)
includeTags 和 excludeTags 接受白名单/黑名单 HTML 标记、类和 ID 的列表:
# Crawl the first 5 pages of the stripe API documentation
stripe_crawl_result = app.crawl_url(
url="https://docs.stripe.com/api",
params={
"limit": 5,
"scrapeOptions": {
"formats": ["markdown", "html"],
"includeTags": ["code", "#page-header"],
"excludeTags": ["h1", "h2", ".main-content"],
},
},
)
抓取大型网站可能需要很长时间,在适当的情况下,这些小调整会对运行时间产生很大影响。
URL控制
除了抓取配置外,你还有四个选项可用于指定在抓取过程中包含或排除的URL模式:
includePaths- 针对特定部分excludePaths- 避免不需要的内容allowBackwardLinks- 处理交叉引用allowExternalLinks- 管理外部内容
以下是使用这些参数的请求示例:
# URL 控制参数示例
url_control_result = app.crawl_url(
url="https://docs.stripe.com/",
params={
# 仅抓取 /payments 路径下的页面
"includePaths": ["/payments/*"],
# 跳过终端和金融连接部分
"excludePaths": ["/terminal/*", "/financial-connections/*"],
# 允许抓取指向已访问页面的链接
"allowBackwardLinks": False,
# 不跟踪指向外部域的链接
"allowExternalLinks": False,
"scrapeOptions": {
"formats": ["html"]
}
}
)
# 打印已抓取的网页总数
print(f"Total pages crawled: {url_control_result['total']}")
Total pages crawled: 134
在本示例中,我们使用特定的 URL 控制参数抓取 Stripe 文档网站:
爬虫从 https://docs.stripe. com/ 并只抓取 "/payments/*"路径下的页面明确排除 "/terminal/*"和"/financial-connections/*"部分通过将 allowBackwardLinks 设置为 false,它不会重新访问已抓取的页面 外部链接被忽略( allowExternalLinks: false)刮擦配置为只抓取 HTML 内容
这种有针对性的方法有助于将抓取重点放在相关内容上,同时避免不必要的页面,从而使抓取更高效,并将重点放在我们需要的特定文档部分上。
另一个关键参数是 maxDepth(最大深度),它可以让你控制爬虫从起始 URL 开始深入多少层。例如,maxDepth为 2 意味着爬虫将抓取初始页面及其链接的页面,但不会进一步深入。
下面是 Stripe API 文档中的另一个请求示例:
# URL 控制参数示例
url_control_result = app.crawl_url(
url="https://docs.stripe.com/",
params={
"limit": 100,
"maxDepth": 2,
"allowBackwardLinks": False,
"allowExternalLinks": False,
"scrapeOptions": {"formats": ["html"]},
},
)
# 打印抓取的网页总数
print(f"Total pages crawled: {url_control_result['total']}")
Total pages crawled: 99
注意:当页面有分页(如第 2、3、4 页)时,在使用 maxDepth 时,这些分页页面不会算作额外的深度级别。
性能与限制
limit 参数在前面的示例中已经使用过,它对于控制网络抓取的范围至关重要。它设定了将被抓取的最大页面数,这在抓取大型网站或启用外部链接时尤为重要。如果没有这个限制,爬虫可能会遍历一连串无穷无尽的连接页面,从而消耗不必要的资源和时间。
虽然限制参数有助于控制抓取的广度,但还需要确保抓取的每个页面的质量和完整性。为确保抓取到所有需要的内容,可以启用waitFor,让页面完全加载。例如,有些网站使用 JavaScript 来处理动态内容,并使用 iFrames 来嵌入内容或重媒体元素(如视频或 GIF):
stripe_crawl_result = app.crawl_url(
url="https://docs.stripe.com/api",
params={
"limit": 5,
"scrapeOptions": {
"formats": ["markdown", "html"],
"waitFor": 1000, # wait for a second for pages to load
"timeout": 10000, # timeout after 10 seconds
},
},
)
上述代码还将 timeout 参数设置为 10000 毫秒(10 秒),以确保在页面加载时间过长时,爬虫会继续前进而不会卡住。
注意:waitFor持续时间适用于爬虫遇到的所有页面。
同时,必须牢记plan的限制:
使用 Firecrawl 进行异步网络抓取
对于拥有数千页的大型网站来说,即使设计正确,但实际抓取过程也会非常漫长。提高其处理效率,Firecrawl提供了异步抓取功能,可以实现在不阻塞应用程序的情况下开始抓取并监控抓取进度。这在构建需要在抓取过程中保持响应的网络应用程序或服务时特别有用。
异步编程简述
用一个现实世界的比喻来理解异步编程:异步编程就像餐厅服务员同时接受多个订单。他们不用在一张桌子上等顾客用完餐再去下一张桌子,而是可以同时接受多张桌子的订单,将订单提交给厨房,并在准备食物的同时处理其他任务。
在编程方面,代码可以启动多个操作(如网络请求或数据库查询),并在等待响应的同时继续执行其他任务,而不是顺序处理所有内容。
这种方法在网络爬行中尤为重要,因为在网络爬行中,大部分时间都是在等待网络响应--在等待每个页面加载时,你不需要冻结整个应用程序,而是可以通过异步编程并发处理多个页面,从而显著提高效率。
使用async_crawl_url方法
Firecrawl通过async_crawl_url提供了一种直观的异步抓取方法:
app = FirecrawlApp()
crawl_status = app.async_crawl_url("https://docs.stripe.com")
print(crawl_status)
{'success': True, 'id': 'c4a6a749-3445-454e-bf5a-f3e1e6befad7', 'url': 'https://api.firecrawl.dev/v1/crawl/c4a6a749-3445-454e-bf5a-f3e1e6befad7'}
它接受与 crawl_url 相同的参数和抓取选项,但会返回一个抓取状态字典。
可以使用check_crawl_status检查进程的状态,包括抓取任务的 id。
checkpoint = app.check_crawl_status(crawl_status['id'])
print(len(checkpoint['data']))
29
check_crawl_status返回的输出与 crawl_url相同,但只包括迄今为止已抓取的页面。你可以多次运行它,并看到抓取的页面数量在增加。
如果想取消任务,可以使用 cancel_crawl,并传递任务 ID:
final_result = app.cancel_crawl(crawl_status['id'])
print(final_result)
{'status': 'cancelled'}
异步抓取的优势
与 crawl_url 相比,使用 async_crawl_url 有许多优势:
你可以创建多个抓取任务,而无需等待每个任务完成。 可以更有效地监控进度和管理资源。 非常适合批处理或并行抓取任务。 当抓取工作在后台进行时,应用程序仍能保持响应 用户可以监控进度,而无需等待完成 允许实施进度条或状态更新 更容易与消息队列或作业调度程序集成 可以成为大型自动化工作流的一部分 更适合微服务架构
在实际应用中,大型网站几乎都是使用异步抓取。是不是觉得很行呀!
如何保存和存储网站抓取结果
在抓取大型网站时,持久保存抓取结果非常重要。Firecrawl以结构化格式提供抓取的数据,可以轻松保存到各种存储系统中。下面一起来探讨一些常见的方法。
本地文件存储
最简单的方法是保存到本地文件。以下是以不同格式保存抓取内容的方法:
import json
from pathlib import Path
def save_crawl_results(crawl_result, output_dir="firecrawl_output"):
# 如果输出目录不存在,则创建输出目录
Path(output_dir).mkdir(parents=True, exist_ok=True)
# 将完整结果保存为 JSON
with open(f"{output_dir}/full_results.json", "w") as f:
json.dump(crawl_result, f, indent=2)
# 只将标记内容保存为单独文件
for idx, page in enumerate(crawl_result["data"]):
# 从 URL 创建安全文件名
filename = (
page["metadata"]["url"].split("/")[-1].replace(".html", "") or f"page_{idx}"
)
# 保存 markdown 内容
if"markdown"in page:
with open(f"{output_dir}/{filename}.md", "w") as f:
f.write(page["markdown"])
以下是上述函数的作用:
如果输出目录不存在,则创建该目录 将完整的抓取结果保存为 JSON 文件,并适当缩进 为每个抓取到的页面
根据页面 URL 生成文件名 将标记内容保存为单独的 .md 文件
app = FirecrawlApp()
crawl_result = app.crawl_url(url="https://docs.stripe.com/api", params={"limit": 10})
save_crawl_results(crawl_result)
这是一个基本功能,需要针对其他刮擦格式进行修改。
数据库存储
对于更复杂的应用,你可能希望将结果存储在数据库中。下面我们使用 SQLite 的作为示例:
import sqlite3
def save_to_database(crawl_result, db_path="crawl_results.db"):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# 如果不存在则创建
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS pages (
url TEXT PRIMARY KEY,
title TEXT,
content TEXT,
metadata TEXT,
crawl_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"""
)
# Insert pages
for page in crawl_result["data"]:
cursor.execute(
"INSERT OR REPLACE INTO pages (url, title, content, metadata) VALUES (?, ?, ?, ?)",
(
page["metadata"]["url"],
page["metadata"]["title"],
page.get("markdown", ""),
json.dumps(page["metadata"]),
),
)
conn.commit()
print(f"Saved {len(crawl_result['data'])} pages to {db_path}")
conn.close()
该函数会创建一个 SQLite 数据库,其中的 pages 表用于存储抓取的数据。对于每个页面,它都会保存 URL(作为主键)、标题、内容(markdown 格式)和元数据(JSON 格式)。抓取日期会自动添加为时间戳。如果相同 URL 的页面已经存在,它将被新数据取代。这就提供了一个持久的存储解决方案,方便日后查询。
save_to_database(crawl_result)
Saved 9 pages to crawl_results.db
查询数据库,仔细检查一下:
# 查询数据库
conn = sqlite3.connect("crawl_results.db")
cursor = conn.cursor()
cursor.execute("SELECT url, title, metadata FROM pages")
print(cursor.fetchone())
conn.close()
(
'https://docs.stripe.com/api/errors',
'Errors | Stripe API Reference',
{
"url": "https://docs.stripe.com/api/errors",
"title": "Errors | Stripe API Reference",
"language": "en-US",
"viewport": "width=device-width, initial-scale=1",
"sourceURL": "https://docs.stripe.com/api/errors",
"statusCode": 200,
"description": "Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.",
"ogLocaleAlternate": []
}
)
云存储
对于生产应用程序,你可能希望将结果存储在云存储中。下面是一个使用 AWS S3 的示例:
import boto3
from datetime import datetime
def save_to_s3(crawl_result, bucket_name, prefix="crawls"):
s3 = boto3.client("s3")
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
# Save full results
full_results_key = f"{prefix}/{timestamp}/full_results.json"
s3.put_object(
Bucket=bucket_name,
Key=full_results_key,
Body=json.dumps(crawl_result, indent=2),
)
# Save individual pages
for idx, page in enumerate(crawl_result["data"]):
if"markdown"in page:
page_key = f"{prefix}/{timestamp}/pages/{idx}.md"
s3.put_object(Bucket=bucket_name, Key=page_key, Body=page["markdown"])
print(f"Successfully saved {len(crawl_result['data'])} pages to {bucket_name}/{full_results_key}")
以下是该函数的作用:
将抓取结果字典、S3 bucket 名称和一个可选前缀作为输入 在 S3 中创建一个带有时间戳的文件夹结构,以组织数据 将完整的抓取结果保存为一个 JSON 文件 对于每个带有标记内容的抓取页面,将其保存为一个单独的 . md文件使用 boto3 处理 AWS S3 交互 保留抓取数据的层次结构
要使用该函数,必须安装boto3,并在~/.aws/credentials文件中保存 AWS 凭据,格式如下:
[default]
aws_access_key_id = your_access_key
aws_secret_access_key = your_secret_key
region = your_region
然后,只要已经有一个 S3 存储桶来存储数据,就可以执行该函数:
save_to_s3(crawl_result, "sample-bucket-1801", "stripe-api-docs")
Successfully saved 9 pages to sample-bucket-1801/stripe-api-docs/20241118_142945/full_results.json
使用异步抓取进行增量保存
使用异步抓取时,你可能希望在抓取到结果时进行增量保存:
import time
def save_incremental_results(app, crawl_id, output_dir="firecrawl_output"):
Path(output_dir).mkdir(parents=True, exist_ok=True)
processed_urls = set()
while True:
# Check current status
status = app.check_crawl_status(crawl_id)
# Save new pages
for page in status["data"]:
url = page["metadata"]["url"]
if url not in processed_urls:
filename = f"{output_dir}/{len(processed_urls)}.md"
with open(filename, "w") as f:
f.write(page.get("markdown", ""))
processed_urls.add(url)
# Break if crawl is complete
if status["status"] == "completed":
print(f"Saved {len(processed_urls)} pages.")
break
time.sleep(5) # Wait before checking again
以下是该函数的作用:
如果输出目录不存在,则创建该目录 维护一组已处理的 URL,以避免重复 持续检查抓取状态,直至完成 对于找到的每个新页面,将其标记内容保存到一个编号文件 在两次状态检查之间休眠 5 秒,以避免过多的 API 调用
在应用程序抓取 Books-to-Scrape 网站时使用它:
# Start the crawl
crawl_status = app.async_crawl_url(url="https://books.toscrape.com/")
# Save results incrementally
save_incremental_results(app, crawl_status["id"])
Saved 705 pages.
利用 Firecrawl 和 LangChain 集成构建人工智能驱动的网络爬虫
Firecrawl 与 LangChain 等流行的开源库和其他平台集成。
在本节中,我们将了解如何使用 LangChain 集成在 LangChain Community Integrations[1] 网站上构建一个基本的 QA 聊天机器人。
首先安装 LangChain 及其相关库:
pip install langchain langchain_community langchain_anthropic langchain_openai
然后,将 ANTHROPIC_API_KEY 和 OPENAI_API_KEY 作为变量添加到.env文件中。
接下来,从文档加载器模块中导入 FireCrawlLoader 类并对其进行初始化:
from dotenv import load_dotenv
from langchain_community.document_loaders.firecrawl import FireCrawlLoader
load_dotenv()
loader = FireCrawlLoader(
url="https://python.langchain.com/docs/integrations/providers/",
mode="crawl",
params={"limit": 5, "scrapeOptions": {"onlyMainContent": True}},
)
该类可以自动读取你的 Firecrawl API 密钥,因为我们是使用 load_dotenv() 来加载变量的。
要开始抓取,可以调用加载器对象的 load() 方法,抓取的内容就会变成兼容 LangChain 的文档:
# Start the crawl
docs = loader.load()
下一步是分块:
from langchain_text_splitters import RecursiveCharacterTextSplitter
# Add text splitting before creating the vector store
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
# Split the documents
split_docs = text_splitter.split_documents(docs)
上面,我们使用RecursiveCharacterTextSplitter将文档分割成小块。这有助于文本处理,并确保在创建嵌入和执行检索时获得更好的结果。分块大小为 1,000 个字符,重叠部分为 100 个字符,在上下文保护和粒度之间取得了良好的平衡。
from langchain_chroma import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores.utils import filter_complex_metadata
# Create embeddings for the documents
embeddings = OpenAIEmbeddings()
# Create a vector store from the loaded documents
docs = filter_complex_metadata(docs)
vector_store = Chroma.from_documents(docs, embeddings)
接下来,我们使用 Chroma 和 OpenAI 嵌入创建一个向量存储。通过向量存储,我们可以对文档进行语义搜索和检索。我们还过滤掉了可能导致存储问题的复杂元数据。
最后一步是使用 Claude 3.5 Sonnet 作为语言模型构建 QA 链:
from langchain.chains import RetrievalQA
from langchain_anthropic import ChatAnthropic
# Initialize the language model
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620", streaming=True)
# Create a QA chain
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vector_store.as_retriever(),
)
现在,我们可以就文件提出问题了:
# Example question
query = "What is the main topic of the website?"
answer = qa_chain.invoke(query)
print(answer)
{
'query': 'What is the main topic of the website?',
'result': """The main topic of the website is LangChain's integrations with Hugging Face.
The page provides an overview of various LangChain components that can be used with
Hugging Face models and services, including:
1. Chat models
2. LLMs (Language Models)
3. Embedding models
4. Document loaders
5. Tools
The page focuses on showing how to use different Hugging Face functionalities within
the LangChain framework, such as embedding models, language models, datasets, and
other tools."""
}
本节演示了为使用 Firecrawl 抓取的内容构建基本 RAG 管道的过程。在这个版本中,我们只使用了 LangChain 文档中的 10 个页面。随着信息量的增加,管道需要进一步完善。为了有效地扩展该管道,我们需要考虑以下几个因素:
分块策略优化 嵌入模型选择 矢量存储性能调优 针对大型文档集的提示工程
写在最后
在本文中,我们探索了 Firecrawl 的 /crawl 端点及其用于大规模网络爬虫的功能。从基本使用到高级配置,我们涵盖了URL控制、性能优化和异步操作。我们还考察了实际实现,包括数据存储解决方案和与 LangChain 等框架的集成。
端点能够处理 JavaScript 内容、分页和各种输出格式,是满足现代网络刮擦需求的多功能工具。无论是构建文档聊天机器人还是收集训练数据,Firecrawl 都能为你提供强大的基础。通过利用所讨论的配置选项和最佳实践,你可以根据自己的特定需求量身打造高效、可扩展的网络爬虫解决方案。
欢迎大家讨论~点赞支持一下🙏
LangChain Community Integrations: https://python.langchain.com/docs/integrations/providers/