2.4.2 内置解析器
Bricks
框架内置了多种强大的解析器,用于从不同格式的数据中提取所需信息。这些解析器位于 bricks.lib.extractors
模块中,提供了统一的接口和丰富的功能。
解析器概览
Bricks
内置了以下解析器:
解析器名称 | 类名 | 适用场景 | 返回类型 |
---|---|---|---|
XPath 解析器 | XpathExtractor | HTML/XML 文档解析 | list |
JSON 解析器 | JsonExtractor | JSON 数据解析,支持 JMESPath 语法 | 根据表达式而定 |
JSONPath 解析器 | JsonpathExtractor | JSON 数据解析,支持 JSONPath 语法 | 根据表达式而定 |
正则表达式解析器 | RegexExtractor | 文本模式匹配 | list |
XPath 解析器
XPath 解析器用于解析 HTML 和 XML 文档,支持完整的 XPath 语法。
基本信息
- 类名:
XpathExtractor
- is_array:
True
(返回列表) - empty:
(None, [])
方法
extract(obj, exprs, parser=None, base_url=None)
参数说明:
参数名 | 参数类型 | 参数描述 | 默认值 |
---|---|---|---|
obj | Union[etree.HTML, str] | 要解析的 HTML/XML 对象或字符串 | 必传 |
exprs | str | XPath 表达式 | 必传 |
parser | Optional | lxml 解析器 | None |
base_url | Optional[str] | 基础 URL | None |
示例:
from bricks.lib.extractors import XpathExtractor
html = """
<html>
<body>
<div class="content">
<h1>标题</h1>
<p>段落1</p>
<p>段落2</p>
</div>
</body>
</html>
"""
# 提取所有段落文本
paragraphs = XpathExtractor.extract(html, "//p/text()")
print(paragraphs) # ['段落1', '段落2']
# 提取标题
title = XpathExtractor.extract(html, "//h1/text()")
print(title) # ['标题']
# 提取第一个段落
first_p = XpathExtractor.extract_first(html, "//p/text()")
print(first_p) # '段落1'
JSON 解析器
JSON 解析器使用 JMESPath 语法解析 JSON 数据,功能强大且灵活。
基本信息
- 类名:
JsonExtractor
- is_array:
False
(返回单个值) - empty:
(None,)
方法
extract(obj, exprs, jsonp=False, errors="strict", options=None)
参数说明:
参数名 | 参数类型 | 参数描述 | 默认值 |
---|---|---|---|
obj | Union[dict, list, str] | 要解析的 JSON 对象或字符串 | 必传 |
exprs | str | JMESPath 表达式 | 必传 |
jsonp | bool | 是否支持 JSONP 格式 | False |
errors | str | 错误处理方式 | "strict" |
options | Optional[dict] | JMESPath 选项 | None |
示例:
from bricks.lib.extractors import JsonExtractor
data = {
"users": [
{"name": "Alice", "age": 25, "city": "北京"},
{"name": "Bob", "age": 30, "city": "上海"},
{"name": "Charlie", "age": 35, "city": "广州"}
],
"total": 3
}
# 提取用户总数
total = JsonExtractor.extract(data, "total")
print(total) # 3
# 提取所有用户名
names = JsonExtractor.extract(data, "users[*].name")
print(names) # ['Alice', 'Bob', 'Charlie']
# 提取年龄大于 25 的用户
adults = JsonExtractor.extract(data, "users[?age > `25`]")
print(adults) # [{'name': 'Bob', 'age': 30, 'city': '上海'}, {'name': 'Charlie', 'age': 35, 'city': '广州'}]
# 提取第一个用户的城市
first_city = JsonExtractor.extract(data, "users[0].city")
print(first_city) # '北京'
JSONPath 解析器
JSONPath 解析器提供了另一种 JSON 数据解析方式,语法与 XPath 类似。
基本信息
- 类名:
JsonpathExtractor
- is_array:
False
(返回单个值) - empty:
(None,)
方法
extract(obj, exprs, jsonp=False, errors="strict", result_type="VALUE", debug=0, use_eval=True)
参数说明:
参数名 | 参数类型 | 参数描述 | 默认值 |
---|---|---|---|
obj | Union[dict, list, str] | 要解析的 JSON 对象或字符串 | 必传 |
exprs | str | JSONPath 表达式 | 必传 |
jsonp | bool | 是否支持 JSONP 格式 | False |
errors | str | 错误处理方式 | "strict" |
result_type | str | 结果类型 | "VALUE" |
debug | int | 调试级别 | 0 |
use_eval | bool | 是否使用 eval | True |
示例:
from bricks.lib.extractors import JsonpathExtractor
data = {
"store": {
"book": [
{"title": "Python编程", "price": 29.99},
{"title": "数据结构", "price": 39.99},
{"title": "算法导论", "price": 59.99}
]
}
}
# 提取所有书籍标题
titles = JsonpathExtractor.extract(data, "$.store.book[*].title")
print(titles) # ['Python编程', '数据结构', '算法导论']
# 提取价格小于 40 的书籍
cheap_books = JsonpathExtractor.extract(data, "$.store.book[?(@.price < 40)]")
print(cheap_books) # [{'title': 'Python编程', 'price': 29.99}, {'title': '数据结构', 'price': 39.99}]
# 提取第一本书的价格
first_price = JsonpathExtractor.extract(data, "$.store.book[0].price")
print(first_price) # [29.99]
正则表达式解析器
正则表达式解析器用于从文本中提取符合特定模式的内容。
基本信息
- 类名:
RegexExtractor
- is_array:
True
(返回列表) - empty:
(None, [], "")
方法
extract(obj, exprs, flags=0)
参数说明:
参数名 | 参数类型 | 参数描述 | 默认值 |
---|---|---|---|
obj | str | 要匹配的文本 | 必传 |
exprs | str | 正则表达式 | 必传 |
flags | int | 正则表达式标志 | 0 |
示例:
from bricks.lib.extractors import RegexExtractor
text = """
联系方式:
电话:138-1234-5678
邮箱:user@example.com
网站:https://www.example.com
"""
# 提取电话号码
phones = RegexExtractor.extract(text, r"1[3-9]\d-\d{4}-\d{4}")
print(phones) # ['138-1234-5678']
# 提取邮箱地址
emails = RegexExtractor.extract(text, r"\w+@\w+\.\w+")
print(emails) # ['user@example.com']
# 提取 URL
urls = RegexExtractor.extract(text, r"https?://[^\s]+")
print(urls) # ['https://www.example.com']
# 提取第一个匹配的电话号码
first_phone = RegexExtractor.extract_first(text, r"1[3-9]\d-\d{4}-\d{4}")
print(first_phone) # '138-1234-5678'
解析器基类
所有解析器都继承自 Extractor
基类,提供了统一的接口:
通用方法
extract_first(obj, exprs, default=None, **kwargs)
提取第一个匹配结果,如果没有匹配则返回默认值。
match(obj, rules)
根据规则字典进行批量匹配,支持复杂的数据提取场景。
示例:使用 match 方法
from bricks.lib.extractors import JsonExtractor
data = {
"products": [
{"name": "笔记本电脑", "price": 5999, "category": "电子产品"},
{"name": "手机", "price": 2999, "category": "电子产品"},
{"name": "书籍", "price": 29, "category": "图书"}
]
}
# 使用 match 方法提取结构化数据
rules = {
"total_products": "length(products)",
"products[*]": {
"product_name": "name",
"product_price": "price",
"is_expensive": "price > `1000`"
}
}
result = JsonExtractor.match(data, rules)
print(result)
这将输出包含所有产品信息的结构化数据,每个产品都包含名称、价格和是否昂贵的标识。