fix: 多地址面板选择默认地址 (#187)

This commit is contained in:
chengma
2026-08-12 16:25:46 +08:00
parent 2c4f630bed
commit 9c014efc41
2 changed files with 256 additions and 4 deletions
+66 -4
View File
@@ -202,6 +202,68 @@ def _clickable_text_targets(root: ET.Element, exact_text: str) -> list[Bounds]:
return sorted(targets)
def _node_package(
node: ET.Element, parents: Mapping[ET.Element, ET.Element]
) -> str:
"""返回节点自身或最近祖先声明的包名。"""
current: Optional[ET.Element] = node
while current is not None:
if package_name := current.get("package", "").strip():
return package_name
current = parents.get(current)
return ""
def _pdd_text_targets(root: ET.Element, exact_text: str) -> list[Bounds]:
"""只返回 PDD 页面中指定文字的最近点击容器。"""
parents = _parent_nodes(root)
targets = {
bounds
for node in root.iter("node")
if exact_text
in {
node.get("text", "").strip(),
node.get("content-desc", "").strip(),
}
if _node_package(node, parents) == PDD_PACKAGE_NAME
if (bounds := _nearest_clickable_bounds(node, parents)) is not None
}
return sorted(targets)
def _address_modify_targets(root: ET.Element) -> list[Bounds]:
"""多地址时只返回唯一“已设默认”卡片内的修改按钮。"""
address_cards = [
card
for recycler in root.iter("node")
if recycler.get("class") == "androidx.recyclerview.widget.RecyclerView"
for card in list(recycler)
if _pdd_text_targets(card, "修改")
]
if len(address_cards) <= 1:
return _pdd_text_targets(root, "修改")
default_cards = [
card for card in address_cards if "已设默认" in _labels(card)
]
if len(default_cards) != 1:
return []
return _pdd_text_targets(default_cards[0], "修改")
def _pdd_title_back_targets(root: ET.Element) -> list[Bounds]:
"""只返回 PDD 地址页标题栏左侧的返回目标。"""
return [
bounds
for bounds in _pdd_text_targets(root, "返回")
if bounds[0] <= 240 and bounds[1] <= 320
]
def _address_entry_targets(root: ET.Element) -> list[Bounds]:
"""通过脱敏手机号结构定位规格面板顶部的收货地址卡片。"""
@@ -266,9 +328,9 @@ def _is_reliable_address_panel(
labels = _labels(root)
if "收货地址" not in labels:
return False
if len(_clickable_text_targets(root, "修改")) != 1:
if len(_address_modify_targets(root)) != 1:
return False
if len(_clickable_text_targets(root, "返回")) != 1:
if len(_pdd_title_back_targets(root)) != 1:
return False
if expected_address and any(expected_address in label for label in labels):
return True
@@ -1344,7 +1406,7 @@ class U2PddLivePurchaseAdapter(U2PddPurchaseAdapter, PddLivePurchaseAdapter):
saved_root, saved_page = self._wait_after_address_save(new_address)
if saved_page == "confirmation":
return
back_targets = _clickable_text_targets(saved_root, "返回")
back_targets = _pdd_title_back_targets(saved_root)
self._click_unique_address_target(
back_targets,
"PURCHASE_ADDRESS_BACK_AMBIGUOUS",
@@ -1394,7 +1456,7 @@ class U2PddLivePurchaseAdapter(U2PddPurchaseAdapter, PddLivePurchaseAdapter):
return root
if observed_page == "panel":
targets = _clickable_text_targets(root, "修改")
targets = _address_modify_targets(root)
candidate_count = len(targets)
if candidate_count != 1:
raise PddPurchaseError(