fix: 兼容款式与套餐规格分组 (#166)
This commit is contained in:
@@ -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()),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user