Files
q792602257andClaude Opus 5 104d7fef6b 拆分抓取与交易服务
把需要账号登录态的链路从抓取服务里拆出成独立进程。分界线不是「要不要登录」,
而是抓取无状态、幂等、可多开实例,而交易的写操作不可逆、登录态全局唯一、
订单监控是常驻轮询——同进程时抓取一扩容就会复制出 N 份登录态与 N 个轮询,
同一账号会被并发操作。

- app/shared:配置、错误码、日志、ApiResponse 信封 + Bearer 鉴权 + 异常处理器、
  导航请求头构造器
- app/scraping:站点常量、会话、解析器与 10 个抓取接口,:31107,可多开
- app/trading:登录态查询/重载与健康检查,:31108,只能单实例
- 依赖方向锁为 scraping→shared、trading→shared,两侧互不 import;
  tests/test_architecture.py 用 AST 检查 import 并校验两个 app 的路径不串
- 登录态 UA 在 trading 独立持有:与抓取 UA 值相同但变更理由不同,抓取 UA 为绕
  反爬可随时调整,登录 UA 一改可能触发设备校验使已落盘 cookie 失效
- scripts/login.py 与 AuthSession 共用 auth_site.PROFILES 与 is_logged_in,判据只写一遍
- 同一镜像两个启动命令,交易容器覆盖 command 并设 RAKUTEN_HEALTH_PORT

同时带上此前未提交的 ラクマ 分类接口与登录态基础设施。

验证:239 个离线用例全绿;两个入口真实启动,/health 与鉴权正常。
未验证:真实探测登录态(当前开发机无外网,对站点的连接全部超时)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 15:05:01 +08:00

46 lines
2.0 KiB
Python

"""浏览器导航请求头构造
抓取链路与登录态链路都要把 httpx 请求伪装成一次正常的浏览器页面导航,头部结构
完全一致,只有 User-Agent 以及随之联动的 `sec-ch-ua-mobile` / `sec-ch-ua-platform`
不同。结构留在这里共用,UA 常量则各自持有:
- 抓取侧的 UA(`scraping/core/site.py`、`scraping/core/rakuma_site.py`)为反爬表现服务,
换了只影响抓取成功率。
- 登录态侧的 UA(`trading/core/auth_site.py`)必须与人工登录时浏览器用的那一个一致,
换了可能触发站点的设备校验,使已落盘的 cookie 直接失效。
值今天相同,变更理由不同,因此不合并成一份常量。
"""
from __future__ import annotations
from typing import Final
ACCEPT_LANGUAGE: Final = "ja,en-US;q=0.9,en;q=0.8"
def navigation_headers(user_agent: str, *, mobile: bool) -> dict[str, str]:
"""构造一套完整的浏览器导航请求头
乐天前置 Akamai Bot Manager,请求头不完整时不会直接封禁,而是把响应拖到
~11s(实测与响应体大小无关,22 字节的响应同样耗时 11s);补齐下列头并复用
Akamai 下发的 cookie 后,稳定在 ~0.6-0.9s。ラクマ 无此限速,但沿用同一套头
没有代价,两侧保持一致更省心。
"""
return {
"User-Agent": user_agent,
"Accept": (
"text/html,application/xhtml+xml,application/xml;q=0.9,"
"image/avif,image/webp,image/apng,*/*;q=0.8,"
"application/signed-exchange;v=b3;q=0.7"
),
"Accept-Language": ACCEPT_LANGUAGE,
"sec-ch-ua": '"Chromium";v="131", "Not_A Brand";v="24", "Google Chrome";v="131"',
"sec-ch-ua-mobile": "?1" if mobile else "?0",
"sec-ch-ua-platform": '"iOS"' if mobile else '"Windows"',
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
}