You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Appium Python点击Android端Youtube长按弹出的上下文菜单选项?

问题:Appium自动化长按YouTube图标后无法点击上下文菜单中的“订阅”快捷方式

需求与环境

  • 开发语言:Python
  • 自动化框架:Appium
  • 目标应用:Android端YouTube
  • 操作流程:长按YouTube应用图标 → 点击弹出上下文菜单中的「订阅(Subscriptions)」静态快捷方式
  • 当前状态:长按操作成功,但点击「订阅」无响应(已确认元素可被定位、可见)

问题代码

from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
import time
import os
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.action_chains import ActionChains


def reopen(android_package="com.google.android.youtube", udid="udid_xxx"):
        """
        创建新的驱动对象
        """
        time.sleep(2)
        desired_caps = {
            "deviceName": "MI",
            "platformName": "Android",
            "version": "13",
            "automationName": "Appium",
            "noReset": True,
            "chromedriverExecutable": os.path.join(os.getcwd(), "chromedriver.exe"),
            "showChromedriverLog": True,
            "chromeOptions": {
                "androidPackage": android_package,
                "w3c": False
            },
            "autoGrantPermissions": True,
            "newCommandTimeout": 3000,
            "wdaStartupRetryInterval": 20000,
            "wdaStartupRetries": 4,
            "adbExecTimeout": 20000,
            "ignoreHiddenApiPolicyError": True,
            "udid": udid
        }

        # 创建WebDriver
        driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)

        wait = WebDriverWait(driver, timeout=5)
        by = AppiumBy.XPATH
        # 定位YouTube应用图标
        value = "//android.widget.ImageView[@content-desc='YouTube']"
        element = wait.until(EC.element_to_be_clickable((by, value)))

        # 执行长按操作
        actions = TouchAction(driver)
        actions.long_press(element).perform()
        time.sleep(5)
        # 定位上下文菜单中的「Subscriptions」选项
        tap_element = driver.find_element(AppiumBy.XPATH, "//android.widget.TextView[@text='Subscriptions']")
        # 调试输出:元素可见、文本正确,但点击无效
        print(tap_element.is_displayed())  # 输出 - True
        print(tap_element.text)  # 输出 - Subscriptions
        print(tap_element.is_enabled) # 输出 - <bound method WebElement.is_enabled of <appium.webdriver.webelement.WebElement...>>

        tap_element.click()  # 无响应


if __name__ == '__main__':
     reopen()

解决方案

1. 改用TouchAction/ActionChains模拟点击

系统级上下文菜单的元素可能不响应常规click(),改用触摸动作模拟点击:

# 方法1:TouchAction
actions = TouchAction(driver)
actions.tap(tap_element).perform()

# 方法2:ActionChains
actions = ActionChains(driver)
actions.move_to_element(tap_element).click().perform()

2. 等待元素完全可点击后操作

替换time.sleep(5)为显式等待,确保元素处于可交互状态:

# 等待「订阅」元素可点击
tap_element = wait.until(EC.element_to_be_clickable((AppiumBy.XPATH, "//android.widget.TextView[@text='Subscriptions']")))
tap_element.click()

3. 优化元素定位表达式

尝试更精确的XPATH定位,比如结合父容器属性缩小范围:

# 示例:通过父布局定位
tap_element = wait.until(EC.element_to_be_clickable((AppiumBy.XPATH, "//android.widget.ListView//android.widget.TextView[@text='Subscriptions']")))

4. 使用ADB命令模拟点击

如果上述方法无效,可获取元素坐标后用ADB直接触发点击:

# 获取元素中心坐标
location = tap_element.location
x = location['x'] + tap_element.size['width'] // 2
y = location['y'] + tap_element.size['height'] // 2
# 执行ADB点击命令
os.system(f"adb -s {udid} shell input tap {x} {y}")

5. 更换自动化引擎为UiAutomator2

Android 13对默认Appium引擎兼容性较差,修改desired_caps:

"automationName": "UiAutomator2",

内容的提问来源于stack exchange,提问作者Gobeaner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 20:20:21