Observability
系统化梳理日志、指标与追踪的协同机制及成本控制策略。
通过 Scrapfly API 提取网页中的结构化数据,支持自然语言指令、预训练模型和自定义模板。
openclaw skills install @scrapfly/scrapfly-extraction命令、参数、文件名以原文为准
使用 Scrapfly 数据提取 API,通过大语言模型提示、预训练 AI 模型或自定义提取模板,从 HTML、Markdown 或纯文本中提取结构化数据。
pip install scrapfly-sdkAPI 密钥必须通过环境变量 SCRAPFLY_API_KEY 提供,或直接传递给客户端。
端点: POST https://api.scrapfly.io/extraction
from scrapfly import ScrapflyClient, ExtractionConfig
import os
client = ScrapflyClient(key=os.environ["SCRAPFLY_API_KEY"])| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
body | str | 必填 | 要提取数据的文档内容 |
content_type | str | 必填 | 输入格式:"text/html"、"text/markdown"、"text/plain"、"text/xml" |
url | str | None | 用于解析 HTML 中相对链接的基准 URL |
charset | str | None | 文档编码(若省略则自动检测) |
extraction_prompt | str | None | 用于 LLM 提取的自然语言指令 |
extraction_model | str | None | 预训练模型:"product"、"article"、"review_list"、"real_estate_listing" |
extraction_template | str | None | 自定义模板名称或内联模板定义 |
timeout | int | None | 处理超时时间(单位:秒,范围 60–155) |
webhook_name | str | None | 异步处理时的回调通知名称 |
必须且仅能提供以下三者之一: extraction_prompt、extraction_model 或 extraction_template。
使用自然语言描述需要提取的数据。AI 会理解内容并返回结构化结果。
针对常见数据类型预训练的模型,返回标准化结构和质量评分。
"article" - 新闻/博客文章(标题、作者、日期、正文等)"event" - 活动信息(名称、日期、地点、描述等)"food_recipe" - 食谱(食材、步骤、份量等)"hotel" - 单个酒店/房产(名称、设施、评分等)"hotel_listing" - 酒店搜索/列表结果"job_listing" - 职位搜索/列表结果"job_posting" - 单个职位(职位名称、公司、薪资、描述等)"organization" - 公司/组织(名称、联系方式、描述等)"product" - 电商商品(名称、价格、描述、图片等)"product_listing" - 商品搜索/分类列表"real_estate_property" - 单个房产(价格、地址、特征等)"real_estate_property_listing" - 房产搜索/列表结果"review_list" - 评论列表(评论人、评分、内容、日期等)"search_engine_results" - 搜索引擎结果(结果项、摘要等)"social_media_post" - 社交媒体动态(作者、内容、互动数据等)"software" - 软件/应用(名称、描述、定价等)"stock" - 股票/市场数据"vehicle_ad" - 单个车辆广告"vehicle_ad_listing" - 车辆搜索/列表结果用于在相似页面上保持一致解析的结构化提取规则。可内联定义(JSON 对象形式),也可在 Scrapfly 平台保存后通过别名引用。
若已在 Scrapfly 控制台(数据提取 API → 模板)中保存了模板,请传入其别名字符串。平台会自动解析为当前已发布的版本并应用:
result = client.extract(ExtractionConfig(
body=html_content,
content_type="text/html",
url="https://example.com/product/1",
extraction_template="product-card",
))已保存模板支持:
match_domain / match_path)。对不匹配的 URL 请求将返回 ERR::EXTRACTION::TEMPLATE_URL_MISMATCH 错误。别名格式为小写字母、数字和短横线组合,长度 3 至 128 字符。详见 [已保存的数据提取模板](https://scrapfly.io/docs/extraction-api/templates) 的控制台操作流程。
直接传入 Python 字典以一次性提取,无需保存。适用于临时脚本或每次调用模板不同的场景。
{
"source": "html",
"selectors": [
{
"name": "title",
"query": "h3.product-title::text",
"type": "css",
"formatters": [
{
"name": "uppercase"
}
]
},
{
"name": "description",
"query": "p.product-description::text",
"type": "css"
},
{
"extractor": {
"name": "price"
},
"name": "price",
"query": ".product-price::text",
"type": "css"
},
{
"name": "variants",
"query": "div.variants",
"type": "css",
"nested": [
{
"name": "name",
"query": "//a[@data-variant-id]/@data-variant-id",
"type": "xpath",
"multiple": true
},
{
"name": "link",
"query": "//a[@data-variant-id]/@href",
"type": "xpath",
"multiple": true
}
]
},
{
"name": "reviews",
"query": "div.review>p::text",
"type": "css",
"multiple": true
}
]
}from scrapfly import ScrapflyClient, ExtractionConfig
import os
client = ScrapflyClient(key=os.environ["SCRAPFLY_API_KEY"])
html_content = "<html><body><h1>iPhone 15</h1><span class='price'>$999</span><p>Latest Apple smartphone</p></body></html>"
result = client.extract(ExtractionConfig(
body=html_content,
content_type="text/html",
extraction_prompt="Extract the product name, price, and description as JSON"
))
# result
result.extraction_result['data']
# 或
print(result.data)
# result content_type
result.extraction_result['content_type']
# 或
print(result.content_type)markdown_content = """
# Best Restaurants in NYC
1. **Le Bernardin** - French, $$$, 4.8 stars
2. **Peter Luger** - Steakhouse, $$$, 4.5 stars
3. **Di Fara Pizza** - Italian, $, 4.7 stars
"""
result = client.extract(ExtractionConfig(
body=markdown_content,
content_type="text/markdown",
extraction_prompt="Extract each restaurant as a JSON array with name, cuisine, price_range, and rating fields"
))
print(result.data)from scrapfly import ScrapflyClient, ExtractionConfig, ScrapeConfig
# 先抓取页面,再提取数据
scrape_result = client.scrape(ScrapeConfig(url="https://web-scraping.dev/product/1"))
result = client.extract(ExtractionConfig(
body=scrape_result.content,
content_type="text/html",
url="https://web-scraping.dev/product/1",
extraction_model="product"
))
print(result.data)
# 返回结果:{"name": "...", "price": "...", "currency": "...", "description": "...", ...}result = client.extract(ExtractionConfig(
body=html_content,
content_type="text/html",
extraction_prompt="What is the most expensive item on this page and how much does it cost?"
))
print(result.data)from scrapfly import ScrapflyClient, ScrapeConfig, ExtractionConfig
import os
client = ScrapflyClient(key=os.environ["SCRAPFLY_API_KEY"])
# 步骤 1:抓取页面
scrape_result = client.scrape(ScrapeConfig(
url="https://web-scraping.dev/product/1",
format="markdown"
))
# 步骤 2:从内容中提取结构化数据
extraction_result = client.extract(ExtractionConfig(
body=scrape_result.content,
content_type="text/markdown",
extraction_prompt="Extract all products as a JSON array with fields: name, price, availability"
))
print(extraction_result.data)你也可以在抓取请求中直接进行数据提取:
result = client.scrape(ScrapeConfig(
url="https://web-scraping.dev/product/1",
extraction_prompt="Extract the product name, price, and description as JSON"
))
# 提取结果包含在抓取响应中
print(result.scrape_result["extracted_data"])# 首先,抓取网页以获取其 HTML 内容
api_response = client.scrape(scrape_config=ScrapeConfig(
url='https://web-scraping.dev/product/1',
render_js=True
))
html = api_response.content
# 数据提取模板,用于定义 HTML 解析规则。支持以下字段:
# selectors:CSS、XPath、JMESPath、正则表达式、嵌套选择器(可组合多种类型)
# extractors:用于提取常见数据类型,如价格、图片、链接、邮箱
# formatters:对提取的数据进行格式化处理,如转为小写、大写、时间格式等
# 详细说明请参考文档:https://scrapfly.io/docs/extraction-api/rules-and-template#rules
extraction_template = {
"source": "html",
"selectors": [
{
"name": "title",
"query": "h3.product-title::text",
"type": "css",
"formatters": [
{
"name": "uppercase"
}
],
},
{
"name": "description",
"query": "p.product-description::text",
"type": "css"
},
{
"extractor": {
"name": "price"
},
"name": "price",
"query": ".product-price::text",
"type": "css"
},
{
"name": "variants",
"query": "div.variants",
"type": "css",
"nested": [
{
"name": "name",
"query": "//a[@data-variant-id]/@data-variant-id",
"type": "xpath",
"multiple": True,
},
{
"name": "link",
"query": "//a[@data-variant-id]/@href",
"type": "xpath",
"multiple": True,
},
]
},
{
"name": "reviews",
"query": "div.review>p::text",
"type": "css",
"multiple": True,
}
]
}
extraction_api_response = client.extract(
extraction_config=ExtractionConfig(
body=html, # 传入 HTML 内容
content_type='text/html', # 内容类型
charset='utf-8', # 内容编码,不确定时可使用 `auto`
extraction_ephemeral_template=extraction_template # 临时定义的模板或已保存在仪表板中的模板名称
)
)
# 提取结果数据
print(extraction_api_response.data)
# 提取结果的内容类型
print(extraction_api_response.content_type)from scrapfly.errors import ScrapflyError
try:
result = client.extract(ExtractionConfig(
body="<html><body><h1>iPhone 15</h1><span class='price'>$999</span><p>Latest Apple smartphone</p></body></html",
content_type="text/html",
extraction_prompt="Extract the product price",
))
print(result.data)
except ScrapflyError as e:
print(f"提取失败: {e.message}")extraction_prompt、extraction_model 或 extraction_templateurl 参数有助于解析 HTML 中的相对链接,但非必需format="markdown" 或 format="text" 以减少 token 使用量ScrapeConfig 中添加 extraction_prompt 或 extraction_model已收录 3 个 Skill