OpenClaw + Pangolinfo API:AI Agent 驱动的亚马逊自动化运营原理与工程实践

0 阅读6分钟

HDDUSdeWYAEem8I.jpeg

TL;DR

OpenClaw 作为 AI Agent 执行框架,缺乏实时电商数据是其在跨境场景落地的最大障碍。接入 Pangolinfo API 能从根本上解决这一问题:API 直接返回结构化 JSON,避免了 DIY 爬虫的三重代价(反爬维护、Token 爆炸、规模天花板),让 OpenClaw 真正成为跨境运营团队的"数字员工"。

核心技能包(可直接安装)

git clone https://github.com/Pangolin-spg/openclaw-skill-pangolinfo.git

Tags: #api #python #ecommerce #automation


背景:AI Agent 框架在电商领域的落地困境

AI Agent 框架的核心价值在于任务自主规划 + 工具调用 + 结果反馈的闭环。这个闭环在许多领域已经有了不错的实践,但在跨境电商场景,它面临一个独特挑战:核心决策数据(竞品价格、BSR排名、评论情感)分散在受到强反爬保护的平台页面上,既无法稳定获取,获取后也难以直接供 LLM 消费。

多数开发者尝试了两条路:

路线A:让 AI 写爬虫 → 爬虫不稳定 → 投入大量精力维护 → 数据质量下降 → 项目搁浅
路线B:直接接入结构化数据 API → LLM 零负担消费 JSON → 工作流稳定运行 → 业务持续产出

两条路的结局直接决定了 AI Agent 在这个场景能否真正落地。


核心问题:为什么原始 HTML 会让 AI Agent 失效?

这需要从 LLM 的上下文消耗机制说起。

一个亚马逊商品详情页的原始 HTML 文档,典型体积在 300-600KB 之间。其中:

  • 业务有效信息(价格、BSR、评分、Review数):约 2-4KB(< 1%)
  • CSS 样式、JavaScript 逻辑、广告脚本、冗余标签:约 296-596KB(> 99%)

当这份文档被 tokenize 后输入给 LLM:

# 量化对比示例(基于 cl100k_base tokenizer,GPT-4o系列使用)
import tiktoken

enc = tiktoken.get_encoding("cl100k_base")

# 模拟原始 HTML 输入(450KB HTML 文档)
raw_html_sample = "..."  # 实际 HTML 内容
html_tokens = len(enc.encode(raw_html_sample))
# 典型值:约 100,000 - 120,000 tokens

# Pangolinfo API 返回的结构化 JSON(同一商品)
structured_json_sample = """{
  "asin": "B09XXXXX1",
  "title": "Product Name",
  "price": 29.99,
  "currency": "USD",
  "bsr": 847,
  "bsr_category": "Home & Kitchen",
  "rating": 4.3,
  "review_count": 2847,
  "availability": "In Stock",
  "best_seller_badge": false,
  "variations_count": 6
}"""
json_tokens = len(enc.encode(structured_json_sample))
# 典型值:约 80 - 120 tokens

print(f"原始 HTML Token 数:{html_tokens}")  # ~110,000
print(f"结构化 JSON Token 数:{json_tokens}")  # ~100
print(f"Token 消耗差异:{html_tokens / json_tokens:.0f}x")  # ~1100x

结论:在最极端的情况下,原始 HTML 的 Token 消耗可以达到结构化 JSON 的 1000 倍以上。即使按保守的 100 倍计算,单次任务成本差异也达到两个数量级。


Pangolinfo API 在工程层面做了什么?

Pangolinfo 的价值在于它把数据工程中最难、最脏的部分——反爬穿透 + HTML 解析 + 字段标准化——全部封装在 API 内部,调用方看到的只有干净的 JSON。

这种设计在工程上被称为关注点分离(Separation of Concerns),是构建可维护 AI Agent 工作流的正确方式。

调用方(你的 OpenClaw 工作流)
    │
    │  POST /v1/amazon/product  {"asin": "B09XXX", "marketplace": "US"}
    │
    ▼
Pangolinfo API Layer
    ├── 反爬穿透层:住宅代理轮换 + TLS 指纹模拟 + 行为验证
    ├── 采集层:分布式浏览器渲染集群
    ├── 解析层:亚马逊专用领域解析模板(字段覆盖率 >95%)
    └── 输出层:标准化 JSON / Markdown / 原始 HTML(可选)
    │
    │  {"asin": ..., "price": 29.99, "bsr": 847, ...}
    ▼
调用方收到干净 JSON,直接传入 LLM 推理层

完整工程实现

环境配置

# 克隆 OpenClaw Pangolinfo 技能包
git clone https://github.com/Pangolin-spg/openclaw-skill-pangolinfo.git
cd openclaw-skill-pangolinfo
pip install -r requirements.txt

# 复制并配置
cp config.example.yaml config.yaml
# 编辑 config.yaml,填入 PANGOLINFO_API_KEY

核心客户端实现(带重试逻辑)

import time
import requests
from typing import Optional, List, Dict, Any
from dataclasses import dataclass

@dataclass
class RetryConfig:
    max_attempts: int = 3
    backoff_factor: float = 2.0
    status_forcelist: tuple = (429, 500, 502, 503, 504)

class PangolinfoClient:
    """
    Pangolinfo Scrape API 生产级客户端
    支持指数退避重试、字段过滤、批量请求
    """
    
    BASE_URL = "https://api.pangolinfo.com/v1"
    
    def __init__(self, api_key: str, retry_config: Optional[RetryConfig] = None):
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        self.retry = retry_config or RetryConfig()
    
    def _request(self, endpoint: str, payload: Dict[str, Any]) -> Dict:
        """带指数退避重试的 POST 请求"""
        url = f"{self.BASE_URL}{endpoint}"
        
        for attempt in range(self.retry.max_attempts):
            try:
                resp = requests.post(url, headers=self.headers,
                                     json=payload, timeout=30)
                
                if resp.status_code in self.retry.status_forcelist:
                    wait = self.retry.backoff_factor ** attempt
                    time.sleep(wait)
                    continue
                
                resp.raise_for_status()
                return resp.json()
                
            except requests.exceptions.Timeout:
                if attempt == self.retry.max_attempts - 1:
                    raise
                time.sleep(self.retry.backoff_factor ** attempt)
        
        raise RuntimeError(f"Failed after {self.retry.max_attempts} attempts")
    
    def get_product(self, asin: str, marketplace: str = "US",
                    fields: Optional[List[str]] = None) -> Dict:
        """获取商品详情结构化数据"""
        payload = {"asin": asin, "marketplace": marketplace}
        if fields:
            payload["fields"] = fields
        return self._request("/amazon/product", payload)
    
    def get_reviews(self, asin: str, marketplace: str = "US",
                    page: int = 1) -> Dict:
        """获取评论数据"""
        return self._request("/amazon/reviews", {
            "asin": asin, "marketplace": marketplace,
            "page": page, "sort_by": "recent"
        })
    
    def get_bestseller(self, category_id: str,
                       marketplace: str = "US") -> Dict:
        """获取 BSR 榜单实时数据"""
        return self._request("/amazon/bestseller", {
            "category_id": category_id, "marketplace": marketplace
        })

OpenClaw 工作流集成示例

import json
from datetime import datetime

# 竞品监控工作流(可直接注册为 OpenClaw 技能)
def monitor_competitors(api_key: str,
                        asin_list: List[str],
                        marketplace: str = "US") -> str:
    """
    OpenClaw Skill: 批量监控竞品核心指标
    
    返回值:供 LLM 分析的结构化报告字符串
    LLM 基于此报告决策是否触发告警或策略调整
    """
    client = PangolinfoClient(api_key)
    
    results = []
    for asin in asin_list:
        # 只请求监控所需最小字段集,最大程度压缩 Token
        data = client.get_product(
            asin, marketplace,
            fields=["price", "bsr", "rating", "review_count",
                    "availability", "best_seller_badge"]
        )
        data["asin"] = asin
        data["fetched_at"] = datetime.utcnow().isoformat()
        results.append(data)
    
    # 输出紧凑 JSON 字符串,直接传入 OpenClaw LLM 决策层
    return json.dumps(results, ensure_ascii=False, separators=(",", ":"))


# 评论情感数据采集(注册为 OpenClaw 技能)
def fetch_review_sentiment_data(api_key: str, asin: str,
                                 marketplace: str = "US",
                                 pages: int = 3) -> str:
    """
    OpenClaw Skill: 采集评论数据供 LLM 情感分析
    自动压缩字段,减少 Token 消耗
    """
    client = PangolinfoClient(api_key)
    all_reviews = []
    
    for page in range(1, pages + 1):
        data = client.get_reviews(asin, marketplace, page)
        page_reviews = data.get("reviews", [])
        if not page_reviews:
            break
        # 字段压缩:仅保留情感分析所需字段
        for r in page_reviews:
            all_reviews.append({
                "r": r.get("rating"),           # 评分
                "t": r.get("title", "")[:100],  # 标题(截断)
                "b": r.get("body", "")[:400],   # 正文(截断)
                "v": r.get("verified_purchase"), # 是否已验证购买
                "h": r.get("helpful_votes", 0)  # Helpful 票数
            })
    
    return json.dumps({
        "asin": asin,
        "review_count": len(all_reviews),
        "reviews": all_reviews
    }, ensure_ascii=False, separators=(",", ":"))

最佳实践

1. 字段按需请求(减少 Token 浪费)

# 推荐:只请求当前业务场景所需字段
data = client.get_product("B09XXX", fields=["price", "bsr"])

# 不推荐:默认返回所有字段(Token 多消耗约 3x)
data = client.get_product("B09XXX")

2. 缓存慢变数据

import functools, time

@functools.lru_cache(maxsize=1000)
def cached_product_basic(asin: str, ttl_hour: int = 1) -> dict:
    """
    对变化较慢的字段(商品标题、图片、类目)做缓存
    避免重复计费,降低延迟
    """
    # TTL 通过 time.time() // (ttl_hour * 3600) 控制缓存粒度
    return client.get_product(asin, fields=["title", "category", "brand"])

3. 异常字段做 Fallback

def safe_get_bsr(data: dict) -> Optional[int]:
    """安全读取 BSR,处理缺失或格式异常"""
    bsr = data.get("bsr")
    if isinstance(bsr, int) and bsr > 0:
        return bsr
    return None  # 让上层 LLM 决策层自行处理缺失数据

总结

方案稳定性规模性Token 成本维护成本推荐指数
AI 手写爬虫受限极高(原始 HTML)极高
Pangolinfo API企业级千万页面/天极低(结构化 JSON)

完整技能包及最新示例代码:
GitHub - openclaw-skill-pangolinfo