Crawl4AI入门
欢迎使用 Crawl4AI,这是一款开源的 LLM 友好型网络爬虫和抓取工具。在本教程中,你将学习:
- 使用最小配置运行您的第一次爬网。
- 生成 Markdown 输出(并了解它如何受到内容过滤器的影响)。
- 尝试一种基于 CSS 的简单提取策略。
- 了解基于 LLM 的提取(包括开源和闭源模型选项)。
- 抓取通过 JavaScript 加载内容的动态页面。
1. 简介
Crawl4AI提供:
- 异步爬虫,
AsyncWebCrawler
。 - 可通过以下方式配置浏览器和运行设置
BrowserConfig
和CrawlerRunConfig
。 - 通过以下方式自动将 HTML 转换为 Markdown
DefaultMarkdownGenerator
(支持可选过滤器)。 - 多种提取策略(基于 LLM 或“传统” CSS/XPath)。
在本指南结束时,您将执行基本爬网、生成 Markdown、尝试两种提取策略,并爬网使用“加载更多”按钮或 JavaScript 更新的动态页面。
2. 你的第一次爬行
这是一个最小的 Python 脚本,它创建了一个AsyncWebCrawler
,获取网页,并打印其 Markdown 输出的前 300 个字符:
import asyncio
from crawl4ai import AsyncWebCrawler
async def main():
async with AsyncWebCrawler() as crawler:
result = await crawler.arun("https://example.com")
print(result.markdown[:300]) # Print first 300 chars
if __name__ == "__main__":
asyncio.run(main())
发生什么事了?AsyncWebCrawler
启动无头浏览器(默认为 Chromium)。 - 它获取https://example.com
. - Crawl4AI 自动将 HTML 转换为 Markdown。
现在您已经拥有一个简单、可运行的爬网!
3.基本配置(简单介绍)
Crawl4AI 的爬虫可以使用两个主要类进行高度定制:
1.BrowserConfig
:控制浏览器行为(无头或完整 UI、用户代理、JavaScript 切换等)。2.CrawlerRunConfig
:控制每次爬网的运行方式(缓存、提取、超时、挂钩等)。
下面是最低限度使用的示例:
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
async def main():
browser_conf = BrowserConfig(headless=True) # or False to see the browser
run_conf = CrawlerRunConfig(
cache_mode=CacheMode.BYPASS
)
async with AsyncWebCrawler(config=browser_conf) as crawler:
result = await crawler.arun(
url="https://example.com",
config=run_conf
)
print(result.markdown)
if __name__ == "__main__":
asyncio.run(main())
重要提示:默认缓存模式设置为CacheMode.ENABLED
。因此,为了获得新鲜内容,您需要将其设置为CacheMode.BYPASS
我们将在后续教程中探索更高级的配置(例如启用代理、PDF 输出、多标签会话等)。现在,只需注意如何传递这些对象来管理爬取。
4. 生成 Markdown 输出
默认情况下,Crawl4AI 会自动从每个爬取的页面生成 Markdown 文件。不过,具体输出结果取决于你指定了 Markdown 生成器还是内容过滤器。
- :直接将 HTML 转换为 Markdown。
- :应用任何已配置的内容过滤器后,相同的内容(例如,
PruningContentFilter
)。
示例:使用带有DefaultMarkdownGenerator
from crawl4ai import AsyncWebCrawler, CrawlerRunConfig
from crawl4ai.content_filter_strategy import PruningContentFilter
from crawl4ai.markdown_generation_strategy import DefaultMarkdownGenerator
md_generator = DefaultMarkdownGenerator(
content_filter=PruningContentFilter(threshold=0.4, threshold_type="fixed")
)
config = CrawlerRunConfig(
cache_mode=CacheMode.BYPASS,
markdown_generator=md_generator
)
async with AsyncWebCrawler() as crawler:
result = await crawler.arun("https://news.ycombinator.com", config=config)
print("Raw Markdown length:", len(result.markdown.raw_markdown))
print("Fit Markdown length:", len(result.markdown.fit_markdown))
注意:如果您未指定内容过滤器或 markdown 生成器,通常只会看到原始 Markdown。PruningContentFilter
可能会增加50ms
在处理时间方面。我们将在专门的 Markdown 生成教程中深入探讨这些策略。
5.简单数据提取(基于CSS)
Crawl4AI 还可以使用 CSS 或 XPath 选择器提取结构化数据 (JSON)。以下是一个基于 CSS 的简单示例:
新功能!Crawl4AI 现在提供了一个强大的实用程序,可以使用 LLM 自动生成提取模式。只需一次性付费,即可获得可重复使用的模式,实现快速、无需 LLM 的提取:
from crawl4ai import JsonCssExtractionStrategy
from crawl4ai import LLMConfig
# Generate a schema (one-time cost)
html = "<div class='product'><h2>Gaming Laptop</h2><span class='price'>$999.99</span></div>"
# Using OpenAI (requires API token)
schema = JsonCssExtractionStrategy.generate_schema(
html,
llm_config = LLMConfig(provider="openai/gpt-4o",api_token="your-openai-token") # Required for OpenAI
)
# Or using Ollama (open source, no token needed)
schema = JsonCssExtractionStrategy.generate_schema(
html,
llm_config = LLMConfig(provider="ollama/llama3.3", api_token=None) # Not needed for Ollama
)
# Use the schema for fast, repeated extractions
strategy = JsonCssExtractionStrategy(schema)
有关模式生成和高级用法的完整指南,请参阅No-LLM 提取策略。
这是一个基本的提取示例:
import asyncio
import json
from crawl4ai import AsyncWebCrawler, CrawlerRunConfig, CacheMode
from crawl4ai import JsonCssExtractionStrategy
async def main():
schema = {
"name": "Example Items",
"baseSelector": "div.item",
"fields": [
{"name": "title", "selector": "h2", "type": "text"},
{"name": "link", "selector": "a", "type": "attribute", "attribute": "href"}
]
}
raw_html = "<div class='item'><h2>Item 1</h2><a href='https://example.com/item1'>Link 1</a></div>"
async with AsyncWebCrawler() as crawler:
result = await crawler.arun(
url="raw://" + raw_html,
config=CrawlerRunConfig(
cache_mode=CacheMode.BYPASS,
extraction_strategy=JsonCssExtractionStrategy(schema)
)
)
# The JSON output is stored in 'extracted_content'
data = json.loads(result.extracted_content)
print(data)
if __name__ == "__main__":
asyncio.run(main())
为什么这有帮助? - 非常适合重复的页面结构(例如,项目列表、文章)。 - 无需使用 AI 或支付费用。 - 爬虫返回您可以解析或存储的 JSON 字符串。
提示:您可以将原始 HTML 传递给爬虫,而不是 URL。为此,请在 HTML 中添加前缀raw://
。
6. 简单数据提取(基于法学硕士)
对于更复杂或不规则的页面,语言模型可以智能地将文本解析为您定义的结构。Crawl4AI 支持开源或闭源提供商:
- 开源模型(例如,
ollama/llama3.3
,no_token
) - OpenAI 模型(例如
openai/gpt-4
,需要api_token
) - 或者底层库支持的任何提供程序
下面是使用开源风格(无令牌)和闭源的示例:
import os
import json
import asyncio
from pydantic import BaseModel, Field
from crawl4ai import AsyncWebCrawler, CrawlerRunConfig, LLMConfig
from crawl4ai import LLMExtractionStrategy
class OpenAIModelFee(BaseModel):
model_name: str = Field(..., description="Name of the OpenAI model.")
input_fee: str = Field(..., description="Fee for input token for the OpenAI model.")
output_fee: str = Field(
..., description="Fee for output token for the OpenAI model."
)
async def extract_structured_data_using_llm(
provider: str, api_token: str = None, extra_headers: Dict[str, str] = None
):
print(f"\n--- Extracting Structured Data with {provider} ---")
if api_token is None and provider != "ollama":
print(f"API token is required for {provider}. Skipping this example.")
return
browser_config = BrowserConfig(headless=True)
extra_args = {"temperature": 0, "top_p": 0.9, "max_tokens": 2000}
if extra_headers:
extra_args["extra_headers"] = extra_headers
crawler_config = CrawlerRunConfig(
cache_mode=CacheMode.BYPASS,
word_count_threshold=1,
page_timeout=80000,
extraction_strategy=LLMExtractionStrategy(
llm_config = LLMConfig(provider=provider,api_token=api_token),
schema=OpenAIModelFee.model_json_schema(),
extraction_type="schema",
instruction="""From the crawled content, extract all mentioned model names along with their fees for input and output tokens.
Do not miss any models in the entire content.""",
extra_args=extra_args,
),
)
async with AsyncWebCrawler(config=browser_config) as crawler:
result = await crawler.arun(
url="https://openai.com/api/pricing/", config=crawler_config
)
print(result.extracted_content)
if __name__ == "__main__":
asyncio.run(
extract_structured_data_using_llm(
provider="openai/gpt-4o", api_token=os.getenv("OPENAI_API_KEY")
)
)
发生了什么? - 我们定义了一个 Pydantic 模式(PricingInfo
) 描述我们想要的字段。 - LLM 提取策略使用该模式和您的指令将原始文本转换为结构化 JSON。 - 根据提供程序和 api_token,您可以使用本地模型或远程 API。
7.自适应爬行(新!)
Crawl4AI 现在包含智能自适应爬取功能,可自动判断何时已收集到足够的信息。以下是一个简单的示例:
import asyncio
from crawl4ai import AsyncWebCrawler, AdaptiveCrawler
async def adaptive_example():
async with AsyncWebCrawler() as crawler:
adaptive = AdaptiveCrawler(crawler)
# Start adaptive crawling
result = await adaptive.digest(
start_url="https://docs.python.org/3/",
query="async context managers"
)
# View results
adaptive.print_stats()
print(f"Crawled {len(result.crawled_urls)} pages")
print(f"Achieved {adaptive.confidence:.0%} confidence")
if __name__ == "__main__":
asyncio.run(adaptive_example())
自适应爬取有何特别之处? - 自动停止:收集到足够的信息后停止 - 智能链接选择:仅跟踪相关链接 - 置信度评分:了解您的信息的完整性
8. 多 URL 并发(预览)
如果需要并行抓取多个 URL,可以使用arun_many()
默认情况下,Crawl4AI 使用 MemoryAdaptiveDispatcher,根据系统资源自动调整并发度。以下是简要概述:
import asyncio
from crawl4ai import AsyncWebCrawler, CrawlerRunConfig, CacheMode
async def quick_parallel_example():
urls = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3"
]
run_conf = CrawlerRunConfig(
cache_mode=CacheMode.BYPASS,
stream=True # Enable streaming mode
)
async with AsyncWebCrawler() as crawler:
# Stream results as they complete
async for result in await crawler.arun_many(urls, config=run_conf):
if result.success:
print(f"[OK] {result.url}, length: {len(result.markdown.raw_markdown)}")
else:
print(f"[ERROR] {result.url} => {result.error_message}")
# Or get all results at once (default behavior)
run_conf = run_conf.clone(stream=False)
results = await crawler.arun_many(urls, config=run_conf)
for res in results:
if res.success:
print(f"[OK] {res.url}, length: {len(res.markdown.raw_markdown)}")
else:
print(f"[ERROR] {res.url} => {res.error_message}")
if __name__ == "__main__":
asyncio.run(quick_parallel_example())
上面的例子展示了两种处理多个 URL 的方法:1. 流模式(stream=True
): 使用以下方式处理可用的结果async for
2. 批处理模式(stream=False
): 等待所有结果完成
要了解更高级的并发性(例如基于信号量的方法、自适应内存使用限制或自定义速率限制),请参阅高级多 URL 爬取。
8.动态内容示例
有些网站需要多次“页面点击”或动态 JavaScript 更新。下面是一个示例,展示了如何点击“下一页”按钮并等待 GitHub 上新的提交加载,使用BrowserConfig
和CrawlerRunConfig
:
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
from crawl4ai import JsonCssExtractionStrategy
async def extract_structured_data_using_css_extractor():
print("\n--- Using JsonCssExtractionStrategy for Fast Structured Output ---")
schema = {
"name": "KidoCode Courses",
"baseSelector": "section.charge-methodology .w-tab-content > div",
"fields": [
{
"name": "section_title",
"selector": "h3.heading-50",
"type": "text",
},
{
"name": "section_description",
"selector": ".charge-content",
"type": "text",
},
{
"name": "course_name",
"selector": ".text-block-93",
"type": "text",
},
{
"name": "course_description",
"selector": ".course-content-text",
"type": "text",
},
{
"name": "course_icon",
"selector": ".image-92",
"type": "attribute",
"attribute": "src",
},
],
}
browser_config = BrowserConfig(headless=True, java_script_enabled=True)
js_click_tabs = """
(async () => {
const tabs = document.querySelectorAll("section.charge-methodology .tabs-menu-3 > div");
for(let tab of tabs) {
tab.scrollIntoView();
tab.click();
await new Promise(r => setTimeout(r, 500));
}
})();
"""
crawler_config = CrawlerRunConfig(
cache_mode=CacheMode.BYPASS,
extraction_strategy=JsonCssExtractionStrategy(schema),
js_code=[js_click_tabs],
)
async with AsyncWebCrawler(config=browser_config) as crawler:
result = await crawler.arun(
url="https://www.kidocode.com/degrees/technology", config=crawler_config
)
companies = json.loads(result.extracted_content)
print(f"Successfully extracted {len(companies)} companies")
print(json.dumps(companies[0], indent=2))
async def main():
await extract_structured_data_using_css_extractor()
if __name__ == "__main__":
asyncio.run(main())
要点:
- :我们想看请点击“下一页”。
- :我们指定提取策略,通过
session_id
重复使用同一页面。 - 和
wait_for
用于后续页面(page > 0
)单击“下一步”按钮并等待新的提交加载。 - 表示我们不会重新导航,而是继续现有会话。
- 最后,我们调用
kill_session()
清理页面和浏览器会话。
9. 后续步骤
恭喜!您已:
- 执行了基本抓取并打印了 Markdown。
- 使用带有 markdown 生成器的内容过滤器。
- 通过 CSS 或 LLM 策略提取 JSON。
- 使用 JavaScript 触发器处理动态页面。
如果您准备好了解更多信息,请查看:
- 安装:深入了解高级安装、Docker 使用(实验性)或可选依赖项。
- Hooks & Auth:了解如何运行自定义 JavaScript 或使用 cookie、本地存储等处理登录。
- 部署:探索 Docker 中的临时测试或规划即将发布的稳定 Docker 版本。
- 浏览器管理:深入研究用户模拟、隐身模式和并发最佳实践。
Crawl4AI 是一款功能强大且灵活的工具。您可以尽情构建自己的爬虫、数据管道或 AI 驱动的提取流程。祝您爬取愉快!