加 /api/cart/* 接口;加购链路完全归 trading
trading 新增 4 条购物车接口(POST /api/cart/{add,status,clear,remove}),
全部 Bearer 鉴权、走 SiteInteractor(Playwright + storage_state)。同步把
SiteInteractor 从 gateway URL 解耦——lifespan 总是构造与启停,container
字段 worker_site → site,加 asyncio.Lock 让 HTTP 与 worker 共用同一把锁
(同账号串行硬约束)。clear/remove 用 UI 点击 button[aria-label="削除"],
探针回报这是稳定 selector;真账号实测前先用此路径。
抽 ichiba 加购字段解析到 app/shared/purchase_contract.py(常量 +
inventory_flag_for + basket_domain_of + base_form_fields),原本 scraping
与 trading 重复实现同一段 __INITIAL_STATE__.purchase 解析。进一步发现
README 写的「purchase 块是两服务契约」实际未落地——trading 必须 Playwright
开页(httpx 被 TLS 指纹拦死),本地抽比再调 /api/item_detail 更快更新鲜。
删除 scraping 端 PurchaseInfo/PurchaseOption/PurchaseOptionValue 模型、
各站 _purchase_info 函数、tests/test_purchase.py。ItemDetailData 保留
purchase_condition / is_sold_out / purchase_unit / sku 等商品状态字段。
README「加购与下单」段重写。
328 测试全绿(含架构测试守住三方互不 import)。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,6 @@ from app.shared.errors import ScrapeParseError
|
||||
from app.scraping.models.scrape import (
|
||||
Breadcrumb,
|
||||
ItemDetailData,
|
||||
PurchaseInfo,
|
||||
ShippingInfo,
|
||||
ShopSummary,
|
||||
SkuInfo,
|
||||
@@ -50,22 +49,6 @@ def _extract_nuxt(html: str) -> dict:
|
||||
return state
|
||||
|
||||
|
||||
def _purchase_info(state: dict, item: dict) -> PurchaseInfo:
|
||||
"""该站加购走自己的 JSON 接口,字段与市场完全不同(没有 shop_bid)
|
||||
|
||||
选项(choices)的取值结构未取到样本验证,因此只如实回报「有没有选项」,
|
||||
不给出可能不准确的选项定义——带选项的商品需要调用方另行处理。
|
||||
"""
|
||||
choices = as_list(state.get("choices"))
|
||||
return PurchaseInfo(
|
||||
cart_url=as_str(item.get("add_cart_api_url")),
|
||||
form_fields={"item_id": str(as_int(item.get("item_id")))},
|
||||
quantity_field="units",
|
||||
options_field="choice" if choices else "",
|
||||
has_required_options=bool(choices),
|
||||
)
|
||||
|
||||
|
||||
def parse(page: SubsitePage) -> ItemDetailData:
|
||||
"""解析ビックカメラ商品页"""
|
||||
nuxt = _extract_nuxt(page.html)
|
||||
@@ -128,5 +111,4 @@ def parse(page: SubsitePage) -> ItemDetailData:
|
||||
show_inventory=inventory > 0,
|
||||
delivery_message=delivery,
|
||||
),
|
||||
purchase=_purchase_info(as_dict(nuxt.get("state")), item),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user