用自然语言逆向工程任何网站的内部API
现代网站通过隐藏的AJAX调用加载数据:
Strot分析网站并为你发现其内部API调用。
Strot实际上做的是:
即刻体验完整Strot功能(Web UI + API):
使用 Patchright 浏览器
docker run -d --name browser-server -p 5678:5678 synacktra/patchright-headless-server
STROT_ANTHROPIC_API_KEY=sk-ant-apiXXXXXX \
docker compose -f https://raw.githubusercontent.com/vertexcover-io/strot/refs/heads/main/docker-compose.yml up
或者使用 Steel 浏览器
STROT_BROWSER_WS_URL=wss://connect.steel.dev?apiKey=ste-XXXXXX STROT_ANTHROPIC_API_KEY=sk-ant-apiXXXXXX \
docker compose -f https://raw.githubusercontent.com/vertexcover-io/strot/refs/heads/main/docker-compose.yml up
然后访问:
pip install strot
或者使用 uv:
uv pip install strot
import strot
import asyncio
from pydantic import BaseModel
class Review(BaseModel):
title: str | None = None
username: str | None = None
rating: float | None = None
comment: str | None = None
date: str | None = None
async def get_reviews():
# Strot发现加载评论的内部API
source = await strot.analyze(
url="https://www.getcleanpeople.com/product/fresh-clean-laundry-detergent/",
query="带有评分和评论的用户评论",
output_schema=Review,
code_executor="e2b" # 默认为"unsafe"
)
# 使用网站相同的API调用,并完全控制参数
async for reviews in source.generate_data(limit=500, offset=100, sortBy="date desc"):
for review in reviews:
print(f"{review['rating']}⭐ by {review['username']}: {review['comment']}")
if __name__ == "__main__":
asyncio.run(get_reviews())
import strot
import asyncio
from pydantic import BaseModel
class Product(BaseModel):
name: str | None = None
price: float | None = None
rating: float | None = None
availability: str | None = None
description: str | None = None
async def get_products():
# Strot找到加载商品列表的AJAX端点
source = await strot.analyze(
url="https://blinkit.com/cn/fresh-vegetables/cid/1487/1489",
query="列出的商品,包含名称和价格。",
output_schema=Product
)
# 为source设置你选择的代码执行器
source.set_code_executor("e2b")
# 使用自定义过滤和排序访问所有商品
async for products in source.generate_data(limit=100, offset=0, category="vegetables", sortBy="price"):
for product in products:
print(f"{product['name']}: ${product['price']} ({product['rating']}⭐)")
if __name__ == "__main__":
asyncio.run(get_products())
Strot提供一个MCP(模型上下文协议)服务器,使Claude等MCP客户端能够直接分析网站并发现其内部API。
git clone https://github.com/vertexcover-io/strot.git
cd strot && uv sync --group mcp
设置环境变量:
export STROT_ANTHROPIC_API_KEY=sk-ant-apiXXXXXX
export STROT_BROWSER_MODE_OR_WS_URL=headless # 或 'headed' 或 ws://browser-url
如果你想使用托管浏览器,可以这样做:
在Docker中运行无头服务器
docker run -d --name browser-server -p 5678:5678 synacktra/patchright-headless-server
export STROT_BROWSER_MODE_OR_WS_URL=ws://localhost:5678/patchright
或者连接到远程浏览器服务器:
export STROT_BROWSER_MODE_OR_WS_URL=wss://...
$ uv run strotmcp
用法: strotmcp COMMAND
╭─ 命令 ─────────────────────────────────────────────╮
│ http 启动http服务器。 │
│ sse 启动sse服务器。 │
│ stdio 启动stdio服务器。 │
│ streamable-http 启动可流式http服务器。 │
╰────────────────────────────────────────────────────╯
stdio 传输
claude mcp add strot-mcp "uv run strotmcp stdio" --transport stdio \
--env STROT_ANTHROPIC_API_KEY=$STROT_ANTHROPIC_API_KEY STROT_BROWSER_MODE_OR_WS_URL=$STROT_BROWSER_MODE_OR_WS_URL
sse, http, streamable-http 传输
在另一个终端中运行所需传输模式的MCP服务器:
uv run strotmcp sse --port 8888
# uv run strotmcp http --host 0.0.0.0
# uv run strotmcp streamable-http --host 127.0.0.1 --port 8777
将MCP服务器添加到Claude:
claude mcp add strot-mcp http://127.0.0.1:8888/sse --transport sse
测试并验证Strot在不同网站和单个组件上的分析准确性。评估系统支持五种输入类型:
它比较实际结果与预期结果,跟踪源URL匹配、分页键检测、动态参数检测和实体数量准确性等指标。所有评估及其详细分析步骤都存储在Airtable中。
git clone https://github.com/vertexcover-io/strot.git
cd strot && uv sync --group eval
创建一个新的Airtable Base:
Create 按钮Build an app on your ownappXXXXXXXXXXXXXX)创建个人访问令牌:
/create/tokensdata.records:readdata.records:writeschema.bases:readschema.bases:writeCreate token 并复制令牌(例如 patXXXXXXXXXXXXXX)设置环境变量:
export STROT_AIRTABLE_BASE_ID=appXXXXXXXXXXXXXX
export STROT_AIRTABLE_TOKEN=patXXXXXXXXXXXXXX
# 如果你希望评估独立任务,请设置以下变量
export STROT_ANTHROPIC_API_KEY=sk-ant-apiXXXXXX
注意:运行评估时,所需的表会自动创建并带有正确的模式。
$ uv run stroteval
用法: stroteval [OPTIONS]
从文件或标准输入评估多个基于任务或基于任务的输入。
╭─ 参数 ──────────────────────────────────────────────────────────────────╮
│ --file -f JSON/JSONL文件的路径。如果未提供,则从标准输入读取。 │
╰─────────────────────────────────────────────────────────────────────────╯
如果要评估基于任务的输入,请确保API服务器正在运行。
echo '[
{
"job_id": "existing-job-uuid",
"expected_source": "https://api.example.com/reviews",
"expected_pagination_keys": ["cursor", "limit"],
"expected_dynamic_keys": ["sortBy", "category"],
"expected_entity_count": 243
},
{
"site_url": "https://example.com/category/abc",
"query": "Listed products with name and prices",
"expected_source": "https://api.example.com/products",
"expected_pagination_keys": ["limit", "offset"],
"expected_dynamic_keys": ["category", "sortBy"],
"expected_entity_count": 100
},
{
"request": {
"method": "GET",
"url": "https://example.com/api/products",
"type": "ajax",
"queries": {"page": "2", "limit": "50", "sortBy": "price", "category": "electronics"}
},
"expected_pagination_keys": ["page", "limit"],
"expected_dynamic_keys": ["sortBy", "category"]
},
{
"response": {
"value": "",
"request": {
"method": "GET",
"url": "https://example.com/api/reviews",
"type": "ajax"
},
"preprocessor": {"element_selector": ".reviews-container"}
},
"output_schema_file": "review_schema.json",
"expected_entity_count": 10
}
]' | uv run stroteval
MIT许可证 —— 随意使用!
由 Vertexcover Labs 用 ❤️ 制作