Hyper-Solutions/hermes-scraper

GitHub: Hyper-Solutions/hermes-scraper

一个用 Go 编写的爱马仕官网无浏览器数据爬取工具,通过直接调用后端 JSON API 并绕过 DataDome 验证来批量获取产品目录和详情。

Stars: 0 | Forks: 0

# hermes-scraper 它是使用 Go 语言编写的,并使用 [`bogdanfinn/tls-client`](https://github.com/bogdanfinn/tls-client) 来实现浏览器级别的 TLS 指纹,使用 `fhttp` 实现精确的 Chrome 标头排序,以及使用 [Hyper Solutions API](https://hypersolutions.co/) 来获取 DataDome 的 sensor 数据。 ## 工作原理 一切都通过普通的 HTTP 请求运行。一个新的 session 只会被初始化一次,然后被用于多次 API 调用: 1. **GET 主页。** 如果 DataDome 对其进行验证(带有 `dd` 对象的 `403` 响应,或带有 `geo.captcha-delivery.com` 设备链接的 XHR 验证),则通过 Hyper Solutions API 解决它(插页式或滑动验证)。 2. **Post DataDome 标签**(先是 `ch`,然后是 `le`),就像真实的页面加载一样。 3. **GET `/sync-form`** 以生成 `x-xsrf-token` cookie,随后的 API 调用会将其作为标头回传。 4. **调用 JSON API。** 调用 `bck.hermes.com/menu`(类别树)和 `bck.hermes.com/products`(分页列表)来收集 SKU,然后调用 `bck.hermes.com/product` 获取完整详情。Session 会在一定次数的调用后进行轮换。 唯一访问 Hyper Solutions API 的调用是 DataDome 验证和标签发送;其他所有操作都是直接的 HTTP 请求。 ## 环境要求 - Go 1.26+ - 一个 [Hyper Solutions API key](https://hypersolutions.co/keys)(用于 DataDome) - 一个 sticky/session 住宅代理(你用于抓取的 IP 在每个 session 中必须保持稳定) ## 设置说明 ``` export API_KEY="your-hyper-solutions-key" export HTTP_PROXY="http://user-SESSION:pass@host:port" # "SESSION" is replaced with a random id per session ``` 代理必须是 sticky 的。如果代理字符串包含字面量 token `SESSION`,抓取器会在每个 session 替换一个新的随机 id,以便每个 session 都拥有自己的 IP。 ## 使用说明 两个阶段:收集 SKU,然后获取完整的产品详情。 ### 单个市场 ``` go run ./cmd/skus -locale us_en -out skus.json go run ./cmd/products -in skus.json -out products.jsonl ``` ### 每个市场 ``` go run ./cmd/skus -locale all go run ./cmd/products -locale all ``` ### 快速检查 ``` go run ./cmd/products -skus H100044FPG2 -locale us_en ``` ## 参数标志 **`cmd/skus`** — 发现类别并收集 SKU: | 参数标志 | 默认值 | 含义 | |---|---|---| | `-locale` | `all` | 区域设置(例如 `us_en`),或 `all` 表示所有市场 | | `-categories` | `auto` | `auto`(所有类别),`top`(仅顶层,聚合其整个子树),或逗号分隔的列表 | | `-pagesize` | `144` | 列表页面大小 | | `-threads` | `8` | 并发类别爬虫数 | | `-out` | `skus.json` | 输出路径(当 `-locale all` 时,每个市场会添加一个 `-` 后缀) | **`cmd/products`** — 根据 SKU 获取完整产品详情: | 参数标志 | 默认值 | 含义 | |---|---|---| | `-in` | `skus.json` | 来自 `cmd/skus` 的 SKU 目录,或 SKU 的 JSON 数组 | | `-skus` | | 逗号分隔的 SKU,替代 `-in` | | `-locale` | | 区域覆盖,或 `all` 表示所有市场(读取 `skus-.json`) | | `-threads` | `8` | 并发抓取 session 数 | | `-out` | `products.jsonl` | JSONL 输出路径(每行一个原始 `/product` 响应) | ## 输出 `cmd/skus` 会写入一个 SKU 目录以及基本的列表字段。`cmd/products` 写入 **JSONL**:每行一个原始 `/product` 响应,未规范化(即 API 返回的确切内容,包含完整的对象:价格、每种颜色/饰面/尺寸变体、库存、面包屑导航、尺寸、材料等)。因为每条记录都独立成行,所以即使运行被中断,依然会留下一个有效的文件,并且输出可以通过 `jq`、`wc -l` 等工具进行流式处理。在运行结束时,它会打印出带宽、DataDome sensor 调用次数以及推导出的单产品比例。 ## 关于完整性的说明 - 产品 URL 来自 `bck.hermes.com/menu` 类别树,而不是 sitemap(后者并不是可靠的可购买产品列表)。一个顶级类别已经聚合了其整个子树,因此 `-categories top` 几乎是完整的,而且成本要低得多;`-categories auto` 会遍历每一级并进行去重。 - 同一国家的语言变体(例如 `ca_en` 和 `ca_fr`)是相同目录的不同显示语言。 ## 许可证 参见 [LICENSE](LICENSE)。
标签:EVTX分析, 日志审计