Files

316 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: competitor-price-monitor
description: "竞品价格监控 — 多平台竞品价格自动采集、对比分析、定时监控。覆盖 1688、Ozon、Temu、淘宝、京东。一句话触发完整流水线。"
version: 1.0.0
author: Hermes Agent
license: MIT
metadata:
hermes:
tags: [price-monitoring, competitor-analysis, scraping, cron, cross-border, 1688, ozon, temu, taobao, jd]
related_skills:
- web-scraping-toolkit
- proxy-management
- drissionpage-toolkit
- 1688-cross-border-sourcing
- ozon-operations
- camoufox-google-2fa-login
platforms: [1688, ozon, temu, taobao, jd]
cron_compatible: true
---
# 竞品价格监控 (Competitor Price Monitor)
一句话触发:**"监控 [平台] 上 [品类/关键词] 的竞品价格"**,Agent 自动走完整条采集→分析→报告链。
## 触发条件
当用户提到以下任一关键词组合时,加载本 Skill:
- "竞品价格" / "价格监控" / "比价" / "价格采集"
- "监控 [平台] 价格" / "[品类] 竞品分析"
- "对比 [平台A] 和 [平台B] 价格"
- "定时采集 [平台] 价格"
## 平台适配矩阵
| 平台 | 首选方法 | 备选方法 | 反爬强度 | 代理需求 |
|------|---------|---------|---------|---------|
| **1688** | Firecrawl API | CamouFox + 国内住宅代理 | 极高 (阿里云WAF+指纹) | 必须 |
| **淘宝** | CamouFox + 国内代理 | Jina Reader (限简单页) | 高 | 建议 |
| **京东** | Jina Reader / Crawl4AI | CamouFox | 中 | 可选 |
| **Ozon** | CamouFox + 俄罗斯代理 | CDP Auto-Surf | 高 (Cloudflare+滑块) | 必须 |
| **Temu** | Jina Reader / web_extract | CamouFox (卖家端用CDP) | 中 | 可选 |
## 完整工作流
### Phase 1: 参数解析与任务规划
从用户输入中提取:
```python
task_params = {
"platforms": [], # 目标平台列表
"keywords": [], # 搜索关键词 / 品类
"competitor_urls": [], # 指定竞品链接(可选,优先级高于关键词搜索)
"our_prices": {}, # 我方价格对照表(可选)
"max_items": 20, # 每个平台最多采集条数
"output_format": "csv",# csv / json / markdown / hindsight
}
```
### Phase 2: 平台路由 — 自动选择最佳采集方法
```python
from hermes_tools import terminal, web_extract
def scrape_platform(platform: str, keyword: str, max_items: int = 20):
"""根据平台自动选择最佳采集方法"""
if platform == "1688":
return scrape_1688_firecrawl(keyword, max_items)
elif platform == "taobao":
return scrape_taobao_camoufox(keyword, max_items)
elif platform == "jd":
return scrape_jd_jina(keyword, max_items)
elif platform == "ozon":
return scrape_ozon_camoufox(keyword, max_items)
elif platform == "temu":
return scrape_temu_jina(keyword, max_items)
```
### Phase 3: 数据标准化
所有平台采集结果统一为:
```python
@dataclass
class CompetitorPrice:
platform: str # 平台名
product_name: str # 商品名称
brand: str # 品牌
price: float # 价格(统一为人民币)
currency: str # 原始币种
sales_volume: int # 销量(估算)
rating: float # 评分
shop_name: str # 店铺名
product_url: str # 商品链接
image_url: str # 主图链接
scraped_at: str # 采集时间 ISO8601
shipping_info: str # 运费/物流信息
```
### Phase 4: 价格对比分析
如果提供了我方价格:
```python
def compare_prices(our_items: list, competitor_items: list):
"""对比分析,输出差距和调整建议"""
for our in our_items:
matches = find_similar_products(our["name"], competitor_items)
for match in matches:
diff_pct = (match.price - our["price"]) / our["price"] * 100
status = "⬆️ 我方偏低" if diff_pct > 5 else ("⬇️ 我方偏高" if diff_pct < -5 else "≈ 持平")
```
### Phase 5: 报告生成
输出到 `/tmp/competitor_price_report_{timestamp}.{format}`
**CSV 列:** 平台, 商品名称, 品牌, 价格(¥), 销量, 评分, 店铺, 链接, 采集时间, 与我市价差%
**Markdown 报告包含:**
- 概览摘要(各平台均价、价格区间)
- 详细对比表
- 调价建议(偏高/偏低商品清单)
- 趋势标注(如为定时监控)
## 各平台具体采集方案
### 1688 — Firecrawl API(首选)
```python
# API Key: fc-5536880adfa44fb78a3bd9da8dd52b53
import requests, json, re
FIRECRAWL_KEY = "fc-5536880adfa44fb78a3bd9da8dd52b53"
def scrape_1688_firecrawl(keyword: str, max_items: int = 20):
url = f"https://s.1688.com/s/company_offer_page/0_-1_-1.html?keyword={keyword}"
resp = requests.post("https://api.firecrawl.dev/v1/scrape", json={
"url": url,
"formats": ["markdown"],
"waitFor": 5000,
}, headers={
"Authorization": f"Bearer {FIRECRAWL_KEY}",
"Content-Type": "application/json",
})
markdown = resp.json()["data"]["markdown"]
products = parse_1688_markdown(markdown)
return products[:max_items]
```
### 淘宝 — CamouFox 隐身浏览器
```python
from camoufox.sync_api import Camoufox
def scrape_taobao_camoufox(keyword: str, max_items: int = 20):
with Camoufox(headless=True, geoip=True, humanize=True,
proxy={"server": "http://RESIDENTIAL_PROXY:PORT"}) as browser:
page = browser.new_page()
page.goto(f"https://s.taobao.com/search?q={keyword}", timeout=30000)
page.wait_for_selector(".item.J_MouserOnverReq", timeout=15000)
items = page.query_selector_all(".item.J_MouserOnverReq")
results = []
for item in items[:max_items]:
results.append({
"product_name": item.query_selector(".title").inner_text(),
"price": extract_price(item.query_selector(".price").inner_text()),
"shop_name": item.query_selector(".shopname").inner_text(),
"sales_volume": extract_sales(item.query_selector(".deal-cnt").inner_text()),
})
return results
```
**注意:** 淘宝需要国内住宅代理,服务器 IP 会被直接封。如无可用代理,降级为 Jina Reader 尝试(成功率约 40%)。
### 京东 — Jina Reader(快速)
```python
def scrape_jd_jina(keyword: str, max_items: int = 20):
url = f"https://search.jd.com/Search?keyword={keyword}&enc=utf-8"
resp = requests.get(
f"https://r.jina.ai/{url}",
headers={"Accept": "text/plain", "X-With-Links-Summary": "true"}
)
# 从 Markdown 提取商品信息
return parse_jd_markdown(resp.text)[:max_items]
```
### Ozon — CamouFox + 俄罗斯代理
```python
def scrape_ozon_camoufox(keyword: str, max_items: int = 20):
with Camoufox(headless=True, humanize=True,
proxy={"server": "socks5://RU_PROXY:1080"}) as browser:
page = browser.new_page()
page.goto(f"https://www.ozon.ru/search/?text={keyword}", timeout=30000)
# 处理滑块验证码(如触发)
# 提取商品卡片
items = page.query_selector_all("[data-widget='searchResultsV2'] > div")
results = []
for item in items[:max_items]:
price_text = item.query_selector("[data-widget='price']").inner_text()
results.append({
"product_name": item.query_selector("a.tile-hover-target").inner_text(),
"price_rub": extract_number(price_text),
"price_cny": convert_rub_to_cny(extract_number(price_text)),
"rating": extract_rating(item),
})
return results
```
### Temu — Jina Reader / web_extract(轻量快速)
```python
def scrape_temu_web_extract(keyword: str, max_items: int = 20):
"""Temu 页面用 web_extract 直接抓取"""
from hermes_tools import web_extract
results = web_extract([f"https://www.temu.com/search_result.html?search_key={keyword}"])
return parse_temu_markdown(results["results"][0]["content"])[:max_items]
```
## 定时监控(Cron Job
创建定期监控任务,每日/每周自动执行:
```bash
# 通过 Hermes cron 创建
# 示例:每天早 8 点监控 1688 宠物用品竞品价格
cronjob create --name "宠物用品竞品监控" \
--schedule "0 8 * * *" \
--prompt "加载 competitor-price-monitor skill,监控 1688 和 Temu 上「宠物用品」品类的竞品价格,对比我方价格表 /tmp/our_pet_prices.json,生成对比报告并发送到钉钉" \
--deliver "dingtalk"
```
**推荐监控频率:**
- 日更品类:快消品、数码配件(每天)
- 周更品类:家居、工具、服装(每周一)
- 事件驱动:大促前后、竞品上新时(手动触发)
## 代理资源池
```python
# 国内代理(1688/淘宝)
PROXY_CN = "http://RESIDENTIAL_PROXY_CN:PORT"
# 俄罗斯代理(Ozon
PROXY_RU = "socks5://RESIDENTIAL_PROXY_RU:1080"
# 免费代理回退(低可靠性,仅京东等低反爬平台)
def get_free_proxy():
resp = requests.get(
"https://api.proxyscrape.com/v2/?request=displayproxies&protocol=http&timeout=5000&country=all"
)
proxies = resp.text.strip().split("\r\n")
return random.choice(proxies) if proxies else None
```
> **注意:** 免费代理可用率约 5-6%,寿命小时级。重要采集使用付费住宅代理或 Firecrawl。
## 输出文件规范
| 文件 | 路径 | 说明 |
|------|------|------|
| 原始数据 JSON | `/tmp/competitor_raw_{ts}.json` | 完整采集数据 |
| CSV 报告 | `/tmp/competitor_report_{ts}.csv` | Excel 可直接打开 |
| Markdown 报告 | `/tmp/competitor_report_{ts}.md` | 含分析建议 |
| Hindsight 存档 | hgents05.9webs.online | 长期存储(>7天数据) |
## 快速上手示例
### 示例 1:单平台竞品扫描
> "监控 1688 上「蓝牙耳机」竞品价格,前 20 个"
Agent 自动:Firecrawl → 解析 → 标准化 → CSV 报告
### 示例 2:跨平台比价
> "对比 1688、淘宝、京东上「厨房置物架」的价格,输出对比表"
Agent 自动:三平台并行采集 → 统一货币 → 对比分析 → Markdown 报告
### 示例 3:我方价格对标
> "监控 Ozon 上宠物用品竞品价格,跟我方价格表对比,标出偏高/偏低的"
Agent 自动:读取我方价格文件 → 采集竞品 → 逐项对比 → 调价建议
### 示例 4:定时监控
> "建一个 cron,每天早上 8 点监控 1688 和 Temu 日用百货竞品价格"
Agent 自动:创建 cron job → 定时执行 → 报告推送到钉钉
## 关键 Pitfalls
1. **1688 反爬是第一优先级难题** — 不要用浏览器直接访问(IP 秒封),必须走 Firecrawl API 或 CamouFox + 国内住宅代理
2. **淘宝搜索结果页 JS 渲染复杂** — Jina Reader 对淘宝成功率仅约 40%CamouFox + 代理是唯一稳定方案,但需要可用的国内住宅代理
3. **Ozon 有滑块 CAPTCHA** — CamouFox 需要 `humanize=True`,代理必须是俄罗斯 IP
4. **代理是消耗品** — 免费代理随时可能失效,关键任务要有 fallback 机制
5. **价格需要统一币种** — 1688/淘宝/京东是 CNYOzon 是 RUBTemu 是 USD/CNY,必须归一化
6. **避免频繁请求** — 每个平台请求间隔至少 3-5 秒,必要时加随机延迟
7. **Temu 页面结构频繁变化** — 选择器需要定期维护,建议用 web_extract + LLM 解析代替固定 CSS selector
8. **数据时效性** — 采集时间必须记录,7 天前的价格参考价值大幅降低,超过 30 天的数据归档到 Hindsight
## 依赖
- Python: `requests`, `re`, `json`, `datetime`, `csv`, `camoufox`, `scrapling`
- API Keys: Firecrawl (`fc-5536880adfa44fb78a3bd9da8dd52b53`)
- 代理: 国内住宅代理(1688/淘宝),俄罗斯 SOCKS5Ozon
- Hermes 集成: `web_extract`, `cronjob`, `send_message`(钉钉)