实现 site_interact 加购与购物车校验(Playwright 通道)
探针实测发现 httpx 因 TLS/HTTP2 指纹被 Rakuten 拒认(cookie 有效但 站点不识别 session),site_interact 改为全程 Playwright + storage_state。 add_to_cart 与 verify_cart 已实测可用:从商品页 __INITIAL_STATE__ 抽 purchase 块、调用方补 variant_id 与 choice、POST basketDomain、用 cart count JSONP API 与 SPA 渲染后的 cart 页校验。enter_checkout 及之后仍 NotImplementedError:Rakuten 对 checkout 要求 session upgrade(重输密码), 是自动 checkout 的硬墙,未实测过墙方案前留接口缝。 SiteInteractor 类持有 Playwright BrowserContext,由 WorkerRunner 实例 持有、container/main 接线、lifespan 管理生命周期。测试侧 23 个用例, 全套件 333 passed,架构边界守住。 附 5 个探针脚本(scripts/probe_*.py),记录实测路径与响应结构。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+9
-1
@@ -44,6 +44,7 @@ def build_container() -> TradingContainer:
|
||||
from app.trading.worker.evidence import EvidenceStore
|
||||
from app.trading.worker.local_db import LocalDB
|
||||
from app.trading.worker.runner import WorkerRunner
|
||||
from app.trading.worker.site_interact import SiteInteractor
|
||||
|
||||
client = GatewayClient(
|
||||
settings.order_gateway_url,
|
||||
@@ -52,15 +53,18 @@ def build_container() -> TradingContainer:
|
||||
)
|
||||
local_db = LocalDB(settings.trading_db_path_resolved)
|
||||
evidence = EvidenceStore(settings.evidence_path)
|
||||
site = SiteInteractor(auth_session=container.auth_session, settings=settings)
|
||||
runner = WorkerRunner(
|
||||
settings=settings,
|
||||
gateway_client=client,
|
||||
local_db=local_db,
|
||||
evidence=evidence,
|
||||
site=site,
|
||||
)
|
||||
container.worker_client = client
|
||||
container.worker_local_db = local_db
|
||||
container.worker_evidence = evidence
|
||||
container.worker_site = site
|
||||
container.worker_runner = runner
|
||||
|
||||
return container
|
||||
@@ -86,10 +90,12 @@ async def lifespan(app: FastAPI):
|
||||
|
||||
worker_task: asyncio.Task | None = None
|
||||
if container.worker_runner is not None:
|
||||
# 顺序:先开本地 DB(worker 写证据前要先能写库),再起后台任务
|
||||
# 顺序:先开本地 DB 与 SiteInteractor(worker 写证据/发请求前要先就绪),再起后台任务
|
||||
assert container.worker_local_db is not None
|
||||
assert container.worker_client is not None
|
||||
assert container.worker_site is not None
|
||||
await container.worker_local_db.start()
|
||||
await container.worker_site.start() # type: ignore[union-attr]
|
||||
worker_task = asyncio.create_task(
|
||||
container.worker_runner.run(), name="trading-worker"
|
||||
)
|
||||
@@ -113,6 +119,8 @@ async def lifespan(app: FastAPI):
|
||||
await worker_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
if container.worker_site is not None:
|
||||
await container.worker_site.close() # type: ignore[union-attr]
|
||||
if container.worker_local_db is not None:
|
||||
await container.worker_local_db.close()
|
||||
if container.worker_client is not None:
|
||||
|
||||
Reference in New Issue
Block a user