DY 的视频下面,在歌名上都会有几句说明。
我用 appium。取文字的时候,总是找不到,是为什么?
find_element_by_id('com.ss.android.ugc.aweme:id/l7')
错误
selenium.common.exceptions.NoSuchElementException: Message: An element could not be located on the page using the given search parameters.
试了好多次,查了几遍 id 没错。但就是不行。
奇怪
你的 id 是怎么找到的,uiautomatorviewer 截图发下?
不是很清楚这个 DY 视频是啥?但是一般取不到 id 的原因,我知道一些,可以分享一下,帮你解决问题。
首先先确认一下这个 app 是不是内嵌 js 的?如果是,再确认一下是不是动态获取 js 的?如果是,得用个 driver 来启动他。。。(但我看着你这个获取 id 的方式并不是 hybrid 或 web 这种的),貌似是 Native 的
那你在看看这个描述,是不是一开始就能在屏幕内出现,还是说需要滑动一下,才能出现?如果是,你需要加一个滑动事件,让这个描述出现在手机屏幕上;
噢,抖音不存在我说的那个动态 js 的问题,你获取 id 的方式也是对的,为什么会报找不到元素,你在 find 元素之间有 wait 的过程吗?做了隐式等待 显示等待 强制等待其中一个么?
建议在 find 函数加个断点,然后在断点的时候通过 page_source 获取下界面的控件树,看是不是控件树和 uiautomatorviewer 看到的有出入。
试过等待,昨晚发现 page_source 没有这个元素。
找别的元素的时候,page_source 里面都有。到这个就没了。
不明白怎么回事?
[HTTP] --> GET /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/appium/device/system_time
[HTTP] {}
[MJSONWP] Calling AppiumDriver.getDeviceTime() with args: [null,"2a83c17d-a7bf-4fe6-affa-4e84468f0ceb"]
[AndroidDriver] Attempting to capture android device date and time
[ADB] Running 'E:\SDk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:62027 shell date +%Y-%m-%dT%T%z'
[MJSONWP] Responding to client with driver.getDeviceTime() result: "2019-02-12T23:05:40+08:00"
[HTTP] <-- GET /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/appium/device/system_time 200 109 ms - 99
[HTTP]
[HTTP] --> POST /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/element
[HTTP] {"using":"id","value":"com.ss.android.ugc.aweme:id/l7","sessionId":"2a83c17d-a7bf-4fe6-affa-4e84468f0ceb"}
[MJSONWP] Calling AppiumDriver.findElement() with args: ["id","com.ss.android.ugc.aweme:id/l7","2a83c17d-a7bf-4fe6-affa-4e84468f0ceb"]
[BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
[BaseDriver] Waiting up to 0 ms for condition
[AndroidBootstrap] Sending command to android: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.ss.android.ugc.aweme:id/l7","context":"","multiple":false}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.ss.android.ugc.aweme:id/l7","context":"","multiple":false}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: find
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding 'com.ss.android.ugc.aweme:id/l7' using 'ID' with the contextId: '' multiple: false
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.ss.android.ugc.aweme:id/l7]
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Failed to locate element. Clearing Accessibility cache and retrying.
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding 'com.ss.android.ugc.aweme:id/l7' using 'ID' with the contextId: '' multiple: false
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.ss.android.ugc.aweme:id/l7]
[AndroidBootstrap] Received command result from bootstrap
[MJSONWP] Matched JSONWP error code 7 to NoSuchElementError
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {"status":7,"value":"No element found"}
[MJSONWP] Encountered internal error running command: NoSuchElementError: An element could not be located on the page using the given search parameters.
[MJSONWP] at AndroidDriver.callee$0$0$ (C:\Program Files (x86)\Appium\resources\app\node_modules\appium\node_modules\appium-android-driver\lib\commands\find.js:75:11)
[MJSONWP] at tryCatch (C:\Program Files (x86)\Appium\resources\app\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:67:40)
[MJSONWP] at GeneratorFunctionPrototype.invoke [as _invoke] (C:\Program Files (x86)\Appium\resources\app\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:315:22)
[MJSONWP] at GeneratorFunctionPrototype.prototype.(anonymous function) [as throw] (C:\Program Files (x86)\Appium\resources\app\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:100:21)
[MJSONWP] at GeneratorFunctionPrototype.invoke (C:\Program Files (x86)\Appium\resources\app\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:136:37)
[MJSONWP] at run (C:\Program Files (x86)\Appium\resources\app\webpack:\~\babel-polyfill\~\core-js\modules\es6.promise.js:75:1)
[MJSONWP] at C:\Program Files (x86)\Appium\resources\app\webpack:\~\babel-polyfill\~\core-js\modules\es6.promise.js:92:1
[MJSONWP] at flush (C:\Program Files (x86)\Appium\resources\app\webpack:\~\babel-polyfill\~\core-js\modules\_microtask.js:18:1)
[MJSONWP] at process._tickCallback (internal/process/next_tick.js:61:11)
[HTTP] <-- POST /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/element 500 962 ms - 164
[HTTP]
[HTTP] --> GET /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/appium/device/system_time
[HTTP] {}
[MJSONWP] Calling AppiumDriver.getDeviceTime() with args: [null,"2a83c17d-a7bf-4fe6-affa-4e84468f0ceb"]
[AndroidDriver] Attempting to capture android device date and time
[ADB] Running 'E:\SDk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:62027 shell date +%Y-%m-%dT%T%z'
[MJSONWP] Responding to client with driver.getDeviceTime() result: "2019-02-12T23:07:35+08:00"
[HTTP] <-- GET /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/appium/device/system_time 200 102 ms - 99
[HTTP]
[HTTP] --> GET /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/appium/device/system_time
[HTTP] {}
[MJSONWP] Calling AppiumDriver.getDeviceTime() with args: [null,"2a83c17d-a7bf-4fe6-affa-4e84468f0ceb"]
[AndroidDriver] Attempting to capture android device date and time
[ADB] Running 'E:\SDk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:62027 shell date +%Y-%m-%dT%T%z'
[MJSONWP] Responding to client with driver.getDeviceTime() result: "2019-02-12T23:07:35+08:00"
[HTTP] <-- GET /wd/hub/session/2a83c17d-a7bf-4fe6-affa-4e84468f0ceb/appium/device/system_time 200 103 ms - 99
[HTTP]
这好像也只是提示没找到元素。。。
我没太看出别的异常。我的分析对吗?
找元素前加等待时间了吗,一般找不到元素是这个原因~
这个是 find_element 的日志,不是 page_source 的日志吧?
另外,实际界面上,这个元素真的有出现了吗?能否也截个图看看?
[HTTP]
[HTTP] --> GET /wd/hub/session/b9847749-158b-4de8-9dd6-67017f1e1a70/source
[HTTP] {}
[MJSONWP] Calling AppiumDriver.getPageSource() with args: ["b9847749-158b-4de8-9dd6-67017f1e1a70"]
[AndroidBootstrap] Sending command to android: {"cmd":"action","action":"source","params":{}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"action","action":"source","params":{}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: source
[AndroidBootstrap] [UIAUTO STDOUT] [APPIUM-UIAUTO] [debug] Returning result: {"status":0,"value":"
[AndroidBootstrap] [UIAUTO STDOUT] crollable=\"false\" long-clickable=\"false\" password=\"false\" selected=\"false\" bounds=\"[0,1208][720,1280]\" resource-id=\"com.ss.android.ugc.aweme:id\/na\" instance=\"2\"><\/android.widget.LinearLayout><\/android.widget.LinearLayout><\/android.widget.LinearLayout><\/android.widget.LinearLayout><\/android.widget.FrameLayout><\/android.wid
[AndroidBootstrap] Received command result from bootstrap
[AndroidBootstrap] Stream still not complete, waiting up to 60000ms for the data to arrive
[AndroidBootstrap] [UIAUTO STDOUT] get.LinearLayout><\/android.widget.FrameLayout><\/hierarchy>"}[/APPIUM-UIAUTO]
[AndroidBootstrap] Received command result from bootstrap
[MJSONWP] Responding to client with driver.getPageSource() result: "
[HTTP] <-- GET /wd/hub/session/b9847749-158b-4de8-9dd6-67017f1e1a70/source 200 58 ms - 4151
[HTTP]
page_source 的日志,你说的是这一段吗?
就是红框里面那句
有试过对比 page_source 获取到的 xml 树,和 uiautomatorviewer 相比,缺少了哪些元素吗?
按以前经验,确实会有部分元素 viewer 可见,page_source 不可见,例如 webview 里面的元素。但从你的 viewer 截图上看,这个控件及它的上层所属的类应该都是原生布局,不大像是 webview 里面的元素。
我用 appium desktop 试了下,貌似是可以找到的哦。
appium desktop 版本:1.8.2.20181101.4
手机 android 版本:5.1
抖音安装包:大概 2 天前官方下载的,文件名: app_aweGW_v4.3.3_84a2a6f.apk
搜索日志:
[HTTP] --> POST /wd/hub/session/3ac01ec6-d048-4e5d-ac0b-cfd64ba010eb/elements
[HTTP] {"using":"id","value":"com.ss.android.ugc.aweme:id/l7"}
[MJSONWP] Calling AppiumDriver.findElements() with args: ["id","com.ss.android.ugc.aweme:id/l7","3ac01ec6-d048-4e5d-ac0b-cfd64ba010eb"]
[BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
[BaseDriver] Waiting up to 0 ms for condition
[AndroidBootstrap] Sending command to android: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.ss.android.ugc.aweme:id/l7","context":"","multiple":true}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.ss.android.ugc.aweme:id/l7","context":"","multiple":true}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: find
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding 'com.ss.android.ugc.aweme:id/l7' using 'ID' with the contextId: '' multiple: true
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[RESOURCE_ID=com.ss.android.ugc.aweme:id/l7]
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] getElements selector:UiSelector[RESOURCE_ID=com.ss.android.ugc.aweme:id/l7]
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Element[] is null: (0)
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] getElements tmp selector:UiSelector[INSTANCE=0, RESOURCE_ID=com.ss.android.ugc.aweme:id/l7]
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Element[] is null: (1)
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] getElements tmp selector:UiSelector[INSTANCE=1, RESOURCE_ID=com.ss.android.ugc.aweme:id/l7]
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {"status":0,"value":[{"ELEMENT":"5"}]}
[AndroidBootstrap] Received command result from bootstrap
[MJSONWP] Responding to client with driver.findElements() result: [{"ELEMENT":"5"}]
[HTTP] <-- POST /wd/hub/session/3ac01ec6-d048-4e5d-ac0b-cfd64ba010eb/elements 200 194 ms - 89
有一个点要特别留意,如果视频在播放,此时页面处于动态状态,控件树是不会 dump 出来的。得暂停了视频后才能比较快地 dump 出来。具体原理可以百度下 uiautomator dump 控件树原理相关的文章。
用你图里的工具和 uiautomatorviewer 是都能找到元素的。
但是写在代码 里跑就找不到了。。
我试你说的暂停那个先。
=============================================
暂停视频也是不行
我试过命令行下用 adb 里用命令取 xml
不管视频播放停止都可以。。
而且还能找到我要的那个元素
命令行下取 dump .xml 没问题,播放和暂停都可以。
虽然有时也会取不到。
但在我在 python 里执行命令行,就永远取不到了。
我看了你说的暂停那个,但在代码里总是不行。搜了几天也没有提到解决办法的,哎
id 并不是 resource-id