fix: 兼容款式与套餐规格分组 (#166)

This commit is contained in:
chengma
2026-08-11 17:07:17 +08:00
parent f5d91cd707
commit 9c7e715489
5 changed files with 204 additions and 9 deletions
+41 -7
View File
@@ -44,7 +44,17 @@ Bounds = tuple[int, int, int, int]
_BOUNDS_PATTERN = re.compile(r"^\[(\d+),(\d+)\]\[(\d+),(\d+)\]$")
_PRICE_PATTERN = re.compile(r"[¥¥]\s*(\d+(?:\.\d{1,2})?)")
_QUANTITY_PATTERN = re.compile(r"(\d+(?:\.\d+)?)\s*(万|亿)?\s*(\+)?")
_DIMENSION_NAMES = ("颜色分类", "颜色", "尺码", "尺寸", "规格", "型号", "款式")
_DIMENSION_NAMES = (
"颜色分类",
"颜色",
"花色",
"款式",
"尺码",
"尺寸",
"套餐",
"规格",
"型号",
)
_LOGIN_MARKERS = ("手机号登录", "登录后继续", "验证码登录", "账号登录")
_CAPTCHA_MARKERS = ("请完成验证", "拖动滑块", "安全验证", "点击图中")
_READY_MARKERS = ("发起拼单", "立即购买", "单独购买", "免拼购买", "快要抢光")
@@ -420,10 +430,15 @@ def _is_available(node: ET.Element) -> bool:
def _dimension_key(name: str, used: set[str]) -> str:
if "颜色" in name or "款式" in name:
if any(word in name for word in ("颜色", "花色", "款式")):
base = "color"
elif "尺码" in name or "尺寸" in name:
base = "size"
elif "套餐" in name:
# 本项目的稳定结构只有主规格 color 和第二规格 size。商品只有
# “套餐”一组时,它必须作为主规格采价;前面已有款式/颜色时,
# 套餐才是第二规格。不能无条件映射成 size,否则单规格商品无法采集。
base = "size" if "color" in used else "color"
elif "型号" in name:
base = "model"
else:
@@ -446,7 +461,20 @@ def _is_dimension_heading(label: str) -> bool:
if compact in ("确认款式", "確認款式"):
return False
return compact in _DIMENSION_NAMES or compact.endswith(
("分类", "规格", "尺寸", "尺码", "颜色", "型号", "款式", "容量", "类型", "版本", "口味")
(
"分类",
"规格",
"尺寸",
"尺码",
"颜色",
"型号",
"款式",
"套餐",
"容量",
"类型",
"版本",
"口味",
)
)
@@ -1279,9 +1307,13 @@ class PddCollectService:
"""按行蛇形遍历颜色,并在每次点击后立即读取颜色级价格。"""
self._move_color_list_to_left(device)
first_xml, _ = self._read_valid_spec_panel(device)
first_xml, first_snapshot = self._read_valid_spec_panel(device)
source_dimension = next(
(item for item in first_snapshot.dimensions if item.key == "color"),
None,
)
first_rows = self._visible_color_rows(first_xml)
if not first_rows:
if source_dimension is None or not first_rows:
raise PddCollectError(
"PDD_DATA_SPEC_INCOMPLETE", "规格面板没有可识别的颜色分类"
)
@@ -1371,7 +1403,7 @@ class PddCollectService:
"PDD_DATA_SPEC_INCOMPLETE", "规格面板没有采集到颜色"
)
return (
SpecDimension("color", "颜色分类", tuple(ordered_colors)),
SpecDimension("color", source_dimension.name, tuple(ordered_colors)),
samples,
)
@@ -1668,6 +1700,7 @@ class PddCollectService:
"""颜色采价完成后只滚动并收集尺码文字,不点击尺码。"""
sizes: dict[str, bool] = {}
size_name = "尺码"
previous_signature: Optional[
tuple[tuple[str, tuple[str, ...]], ...]
] = None
@@ -1683,6 +1716,7 @@ class PddCollectService:
f"发现尚未支持的规格维度:{dimension.name}",
)
if dimension.key == "size":
size_name = dimension.name
for value in dimension.values:
sizes[value.text] = sizes.get(value.text, False) or value.available
@@ -1711,7 +1745,7 @@ class PddCollectService:
return None
return SpecDimension(
"size",
"尺码",
size_name,
tuple(DimensionValue(text, available) for text, available in sizes.items()),
)