跳到主要内容

结构化抽取:schema / 正则 / LLM

本章讲清 aprocess_html 的第三步(可选):怎么从页面里抽出结构化数据(不是正文 Markdown,而是 {name, price, ...} 这种)。结果进 result.extracted_content(JSON 字符串)。

1. 这一章解决什么

有时你要的不是「正文」,而是字段:商品名+价格、文章标题+作者+日期、页面里所有邮箱。这就是「结构化抽取」。

Crawl4AI 三条路,都继承 ExtractionStrategy(extraction_strategy.py:86),核心方法 run(url, sections):

策略怎么抽要钱?何时用
JsonCssExtractionStrategy / XPath / Lxml你给 CSS/XPath schema免费结构稳定的列表/详情页
RegexExtractionStrategy内置/自定义正则免费邮箱/电话/URL/日期等通用模式
LLMExtractionStrategy自然语言指令或 Pydantic schema要钱版面多变、语义抽取

输入格式很关键:每个策略有 input_format(extraction_strategy.py:91)——schema 类强制用 html(:2012),LLM 默认用 markdown,正则默认 fit_htmlaprocess_html 按这个选喂哪份内容(async_webcrawler.py:902-919)。

2. CSS/XPath schema 抽取(免费、最常用)

2.1 直觉

如果一个列表页有 50 个商品卡,每张卡结构一样——那就告诉 Crawl4AI:「每张卡的容器是 .product(baseSelector),卡里 .title 是名字、.price 是价格(fields)」。它就遍历所有卡、按字段抽。纯 CSS/XPath 选择器,不用模型,极快

2.2 schema 长什么样

示意,非源码:

schema = {
"baseSelector": ".product", # 每个商品卡的容器
"fields": [
{"name": "title", "selector": ".title", "type": "text"},
{"name": "price", "selector": ".price", "type": "text"},
{"name": "link", "selector": "a", "type": "attribute", "attribute": "href"},
],
}

2.3 怎么遍历

抽象基类 JsonElementExtractionStrategy.extract(extraction_strategy.py:1088):

# extraction_strategy.py:1109-1131(精简)
base_elements = self._get_base_elements(parsed_html, self.schema["baseSelector"])
for element in base_elements: # 每个卡片
item = {}
field_data = self._extract_item(element, self.schema["fields"]) # 按字段抽
item.update(field_data)
if item:
results.append(item)

字段类型很丰富(_extract_field,:1148):text / attribute / html / nested(嵌套对象)/ list / nested_list(列表里套对象)。还支持 computed 字段(用表达式或函数从已抽字段算出新值)。

具体解析器有三种实现,差别在底层引擎:JsonCssExtractionStrategy(BeautifulSoup,:1989)、JsonLxmlExtractionStrategy(lxml,更快,:2051)、JsonXPathExtractionStrategy(XPath,:2449)。

2.4 schema 自动生成(省你手写)

手写 schema 烦?generate_schema(extraction_strategy.py:1692)/ agenerate_schema(:1764)用一次 LLM 调用,从一个样例页面自动生成 schema。生成一次后存下来,之后的抽取全是纯 Python、零 LLM 成本——「用一次 LLM 换长期免费抽取」。

3. 正则抽取(通用模式)

RegexExtractionStrategy(extraction_strategy.py:2558)针对通用模式:邮箱、电话、URL、IP、日期、货币、信用卡……内置 21 种(DEFAULT_PATTERNS,:2636-2664),用 IntFlag 位标志让你 bit-OR 组合(:2578-2606):

from crawl4ai import RegexExtractionStrategy as R
# 同时抽邮箱和 URL
strat = R(R.Email | R.Url)
# 结果每条:{url, label, value, span:[start,end]}

纯 Python、零调用。也能传 custom 自定义模式。同样 generate_schema() 能用 LLM 帮你生成正则(:2572 注释:只有 generate_schema 碰 LLM,抽取本身纯 Python)。

4. LLM 抽取(语义、灵活、要钱)

版面多变、或要「语义级」抽取(比如「把每条评论的情感和要点抽出来」)时用 LLMExtractionStrategy(extraction_strategy.py:533)。两种模式:

  • 指令模式:给一句 instruction(自然语言),用 PROMPT_EXTRACT_BLOCKS_WITH_INSTRUCTION
  • schema 模式:给 Pydantic schema,让模型按结构填。

4.1 分块 + 并行

长页面要先分块(chunking),避免超 LLM 上下文。run(extraction_strategy.py:786)先 _merge 按 token 阈值合并/切段(带 overlap_rate 重叠,防止边界切断信息),再处理:

# extraction_strategy.py:804-827(精简)
if provider 是 groq:
for section: extract(...); time.sleep(0.5) # 限速,顺序跑
else:
with ThreadPoolExecutor(max_workers=4): # 并行调 4 路
futures = [submit(extract, ix, section) for ...]

arun(:972)走异步并发,主线优先用它(async_webcrawler.py:931-937)。这就是把「大页面 → 多块 → 并行喂模型 → 合并」做成了流水线。chunking 策略本身在 chunking_strategy.py(RegexChunking 等)。

5. 怎么选

要抽通用模式(邮箱/电话/URL/日期)?
└─ 是 → RegexExtractionStrategy(零成本)
结构稳定、选择器写得出?
└─ 是 → JsonCss/Lxml/XPath schema(零成本;可用 generate_schema 自动生成)
版面多变 / 要语义理解?
└─ 是 → LLMExtractionStrategy(要钱,分块并行)

6. 巧妙之处

  • 「一次 LLM 生成 schema,之后永久免费抽取」(generate_schema)——把 LLM 用在「学规则」而非「每次抽取」,成本结构很聪明。
  • schema 字段支持 nested / list / computed,能抽出嵌套结构,不止平铺字段。
  • LLM 抽取的分块带 overlap,避免在 chunk 边界切断一条记录。

7. 边界

  • CSS/XPath schema 对结构变化敏感:站点改版选择器就失效。
  • 正则只认模式,不懂上下文(抽到的「数字」未必是你要的那个价格)。
  • LLM 抽取要钱、有延迟、可能产生格式不稳的输出(靠 schema 模式约束)。

8. 代码地图

主题文件路径符号名
抽取基类crawl4ai/extraction_strategy.pyExtractionStrategyinput_format
schema 遍历crawl4ai/extraction_strategy.pyJsonElementExtractionStrategy.extract_extract_field
CSS / Lxml / XPathcrawl4ai/extraction_strategy.pyJsonCssExtractionStrategyJsonLxmlExtractionStrategyJsonXPathExtractionStrategy
schema 自动生成crawl4ai/extraction_strategy.pyJsonElementExtractionStrategy.generate_schema
正则抽取crawl4ai/extraction_strategy.pyRegexExtractionStrategyDEFAULT_PATTERNS
LLM 抽取crawl4ai/extraction_strategy.pyLLMExtractionStrategy.runLLMExtractionStrategy.arun
分块crawl4ai/chunking_strategy.pyRegexChunkingIdentityChunking