bricks
开发指南
2.4 解析篇
2.4.2 内置解析器

2.4.2 内置解析器

Bricks 框架内置了多种强大的解析器,用于从不同格式的数据中提取所需信息。这些解析器位于 bricks.lib.extractors 模块中,提供了统一的接口和丰富的功能。

解析器概览

Bricks 内置了以下解析器:

解析器名称类名适用场景返回类型
XPath 解析器XpathExtractorHTML/XML 文档解析list
JSON 解析器JsonExtractorJSON 数据解析,支持 JMESPath 语法根据表达式而定
JSONPath 解析器JsonpathExtractorJSON 数据解析,支持 JSONPath 语法根据表达式而定
正则表达式解析器RegexExtractor文本模式匹配list

XPath 解析器

XPath 解析器用于解析 HTML 和 XML 文档,支持完整的 XPath 语法。

基本信息

  • 类名: XpathExtractor
  • is_array: True (返回列表)
  • empty: (None, [])

方法

extract(obj, exprs, parser=None, base_url=None)

参数说明:

参数名参数类型参数描述默认值
objUnion[etree.HTML, str]要解析的 HTML/XML 对象或字符串必传
exprsstrXPath 表达式必传
parserOptionallxml 解析器None
base_urlOptional[str]基础 URLNone

示例:

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)

参数说明:

参数名参数类型参数描述默认值
objUnion[dict, list, str]要解析的 JSON 对象或字符串必传
exprsstrJMESPath 表达式必传
jsonpbool是否支持 JSONP 格式False
errorsstr错误处理方式"strict"
optionsOptional[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)

参数说明:

参数名参数类型参数描述默认值
objUnion[dict, list, str]要解析的 JSON 对象或字符串必传
exprsstrJSONPath 表达式必传
jsonpbool是否支持 JSONP 格式False
errorsstr错误处理方式"strict"
result_typestr结果类型"VALUE"
debugint调试级别0
use_evalbool是否使用 evalTrue

示例:

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)

参数说明:

参数名参数类型参数描述默认值
objstr要匹配的文本必传
exprsstr正则表达式必传
flagsint正则表达式标志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)

这将输出包含所有产品信息的结构化数据,每个产品都包含名称、价格和是否昂贵的标识。