fix: 识别带价格的纵向套餐续页 (#168)
This commit is contained in:
@@ -1740,9 +1740,12 @@ class PddCollectService:
|
||||
size_name = dimension.name
|
||||
size_found = True
|
||||
for value in dimension.values:
|
||||
if self._is_second_dimension_action(value.text):
|
||||
option_text = self._second_dimension_option_text(value.text)
|
||||
if option_text is None:
|
||||
continue
|
||||
sizes[value.text] = sizes.get(value.text, False) or value.available
|
||||
sizes[option_text] = (
|
||||
sizes.get(option_text, False) or value.available
|
||||
)
|
||||
|
||||
if size_found:
|
||||
break
|
||||
@@ -1827,9 +1830,10 @@ class PddCollectService:
|
||||
)
|
||||
size_name = size_dimension.name
|
||||
for value in size_dimension.values:
|
||||
if self._is_second_dimension_action(value.text):
|
||||
option_text = self._second_dimension_option_text(value.text)
|
||||
if option_text is None:
|
||||
continue
|
||||
sizes[value.text] = sizes.get(value.text, False) or value.available
|
||||
sizes[option_text] = sizes.get(option_text, False) or value.available
|
||||
|
||||
signature = self._second_dimension_signature(xml_data, size_dimension)
|
||||
stable_edge_reads = (
|
||||
@@ -1928,14 +1932,24 @@ class PddCollectService:
|
||||
"""返回已确认的第二规格签名,不要求当前屏仍显示规格标题。"""
|
||||
|
||||
root = _parse_xml(xml_data)
|
||||
targets = {
|
||||
normalized
|
||||
for value in dimension.values
|
||||
if (normalized := self._second_dimension_option_text(value.text))
|
||||
is not None
|
||||
}
|
||||
result = []
|
||||
for value in dimension.values:
|
||||
node = self._find_option_node(root, value.text)
|
||||
if node is None:
|
||||
for node in root.iter("node"):
|
||||
if node.get("clickable") != "true":
|
||||
continue
|
||||
text = self._second_dimension_option_text(
|
||||
_preferred_or_descendant_label(node).strip()
|
||||
)
|
||||
if text not in targets:
|
||||
continue
|
||||
bounds = _parse_bounds(node.get("bounds", ""))
|
||||
if bounds is not None:
|
||||
result.append((value.text, bounds))
|
||||
result.append((text, bounds))
|
||||
return tuple(result)
|
||||
|
||||
def _build_second_dimension_context(
|
||||
@@ -2009,13 +2023,11 @@ class PddCollectService:
|
||||
continue
|
||||
text = _preferred_or_descendant_label(node).strip()
|
||||
bounds = _parse_bounds(node.get("bounds", ""))
|
||||
option_text = self._second_dimension_option_text(text)
|
||||
if (
|
||||
not text
|
||||
or text in seen
|
||||
option_text is None
|
||||
or option_text in seen
|
||||
or bounds is None
|
||||
or self._is_second_dimension_action(text)
|
||||
or bounds[2] - bounds[0]
|
||||
>= (container_bounds[2] - container_bounds[0]) * 0.85
|
||||
):
|
||||
continue
|
||||
if text.endswith(("…", "...")):
|
||||
@@ -2023,8 +2035,8 @@ class PddCollectService:
|
||||
"PDD_DATA_SKU_NAME_TRUNCATED",
|
||||
f"规格名称被截断,无法安全采集:{text}",
|
||||
)
|
||||
seen.add(text)
|
||||
values.append(DimensionValue(text, _is_available(node)))
|
||||
seen.add(option_text)
|
||||
values.append(DimensionValue(option_text, _is_available(node)))
|
||||
if not values:
|
||||
return None
|
||||
return SpecDimension("size", context.name, tuple(values))
|
||||
@@ -2078,13 +2090,11 @@ class PddCollectService:
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _is_second_dimension_action(text: str) -> bool:
|
||||
"""排除规格面板中容易和选项结构相同的操作按钮。"""
|
||||
def _second_dimension_option_text(text: str) -> Optional[str]:
|
||||
"""返回去掉尾部价格的规格文字;操作项或纯价格返回 ``None``。"""
|
||||
|
||||
compact = text.replace(" ", "")
|
||||
if "¥" in compact or "¥" in compact:
|
||||
return True
|
||||
return compact.startswith(("已选", "请选择")) or any(
|
||||
if not compact or compact.startswith(("已选", "请选择")) or any(
|
||||
marker in compact
|
||||
for marker in (
|
||||
"增加数量",
|
||||
@@ -2097,7 +2107,19 @@ class PddCollectService:
|
||||
"确认购买",
|
||||
"关闭",
|
||||
)
|
||||
)
|
||||
):
|
||||
return None
|
||||
if re.fullmatch(
|
||||
r"(?:券后|到手价|拼单价|单买价|价格)?[¥¥]\d+(?:\.\d{1,2})?",
|
||||
compact,
|
||||
):
|
||||
return None
|
||||
normalized = re.sub(
|
||||
r"\s*[¥¥]\s*\d+(?:\.\d{1,2})?\s*$",
|
||||
"",
|
||||
text,
|
||||
).strip()
|
||||
return normalized or None
|
||||
|
||||
def _second_dimension_region(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user