AutoRpa/rpa_cart/cart_ybm.py

84 lines
2.7 KiB
Python

# 药帮忙加入购物车。
from __future__ import annotations
import requests
import urllib3
from cart_add import KIND_OK, KIND_SYSTEM, AddOutcome, classify_mall_message
from cart_match import CartOffer
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
YBM_ADD_URL = "https://www.ybm100.com/new-front/cart/add-product"
# 按再搜到的 sku 把数量加入药帮忙购物车。没有 sku 当系统失败。
def add_ybm_cart(
cookies: dict[str, str],
offer: CartOffer,
qty: int,
*,
session: requests.Session | None = None,
) -> AddOutcome:
sku = _sku_id(offer)
if not sku:
return AddOutcome(kind=KIND_SYSTEM, reason="缺少 sku")
own = session is None
client = session or requests.Session()
try:
if own:
for name, value in cookies.items():
client.cookies.set(name, value)
response = client.post(
YBM_ADD_URL,
json={"skuId": sku, "skuNum": int(qty)},
headers=_headers(),
timeout=30,
verify=False,
)
response.raise_for_status()
return _outcome_from_json(response.json())
except Exception as exc:
return AddOutcome(kind=KIND_SYSTEM, reason=str(exc))
finally:
if own:
client.close()
# 从报价里取药帮忙加车用的 skuId。
def _sku_id(offer: CartOffer) -> str:
raw = offer.extra.get("raw") if isinstance(offer.extra.get("raw"), dict) else offer.extra
if not isinstance(raw, dict):
raw = {}
return str(raw.get("skuId") or offer.sku_id or "")
# 药帮忙加车请求头。
def _headers() -> dict[str, str]:
return {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json",
"Origin": "https://www.ybm100.com",
"Referer": "https://www.ybm100.com/new/",
"X-Requested-With": "XMLHttpRequest",
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36"
),
}
# 把加车回包收成成功、业务失败或系统失败。看不懂的回包当系统失败。
def _outcome_from_json(payload: object) -> AddOutcome:
if not isinstance(payload, dict):
return AddOutcome(kind=KIND_SYSTEM, reason="加购返回异常")
msg = str(payload.get("msg") or payload.get("message") or "")
success = payload.get("success")
code = payload.get("code")
if success is True or code in (0, "0", 200, "200"):
return AddOutcome(kind=KIND_OK)
if msg:
return classify_mall_message(msg)
return AddOutcome(kind=KIND_SYSTEM, reason="加购失败")