《第10章--Android原生App爬虫.pptx》由会员分享,可在线阅读,更多相关《第10章--Android原生App爬虫.pptx(109页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Python Crawler Development Python Crawler Development 极客学院极客学院 JJ互互联网网+职业技能系列技能系列PythonPython爬虫开发爬虫开发 从入门从入门到实战(微课版)到实战(微课版)人民邮电出版社人民邮电出版社谢乾坤谢乾坤著著第第1010章章 AndroidAndroid原生原生AppApp爬虫爬虫 本章本章所讲到的爬虫能够无视网站后台和所讲到的爬虫能够无视网站后台和App数据传递过程中的任何数据传递过程中的任何加密算法,能够爬取任意加密算法,能够爬取任意Android原生原生App显示在屏幕上的文本型数据。显示在屏幕上的文本型
2、数据。并且理论上可以突破任何反爬虫机制。并且理论上可以突破任何反爬虫机制。前面前面的章节所讲到的爬虫无外乎两种情况:第一种情况,爬虫伪的章节所讲到的爬虫无外乎两种情况:第一种情况,爬虫伪装成浏览器,向服务器要数据;第二种情况,在服务器往浏览器发送装成浏览器,向服务器要数据;第二种情况,在服务器往浏览器发送数据时,爬虫从中拦截,获取信息数据时,爬虫从中拦截,获取信息。这这两种情况,无论是暗号(参数)不对还是行为不对,都会被服两种情况,无论是暗号(参数)不对还是行为不对,都会被服务器识别。那么有没有什么办法可以做到几乎毫无痕迹地爬取数据呢务器识别。那么有没有什么办法可以做到几乎毫无痕迹地爬取数据呢
3、?答案是有。当然可能有读者会认为可以使用?答案是有。当然可能有读者会认为可以使用Selenium+ChromeDriver。这种方式只能操作网页。本章将要介绍针对。这种方式只能操作网页。本章将要介绍针对Android原原生生App的爬虫。的爬虫。通过通过这一章的学习,你将会掌握如下知识这一章的学习,你将会掌握如下知识。(1)Android测试环境的搭建。测试环境的搭建。(2)使用)使用Python操作操作Android手机。手机。(3)使用)使用Python操作操作Android手机实现爬虫。手机实现爬虫。10.1 10.1 实现原理实现原理 目前目前,AndroidApp主要有两种实现形式。
4、第一种是主要有两种实现形式。第一种是Android原生原生App。这种这种App的全部或者大部分内容使用的全部或者大部分内容使用Android提供的各个接口来开发,例提供的各个接口来开发,例如如Android版的微信就是一个版的微信就是一个Android原生的原生的App。第二种是基于网页的。第二种是基于网页的App。这种。这种App本质上就是一个浏览器,里面的所有内容实际上都是网页。本质上就是一个浏览器,里面的所有内容实际上都是网页。例如,例如,12306的的App就是这样一种基于网页的就是这样一种基于网页的App。Android原生原生App爬虫(以下简称爬虫(以下简称App爬虫)可以直接
5、读取爬虫)可以直接读取Android原原生生App上面的文本信息,如图上面的文本信息,如图10-1所示。所示。图10-1 App爬虫直接爬虫直接读取取Android原生原生App上面的文本信息上面的文本信息 例如例如想爬想爬TapTap这个这个App上上面的各个游戏,可以直接从手机面的各个游戏,可以直接从手机屏幕上把游戏的名字读出来。当屏幕上把游戏的名字读出来。当然,要读游戏描述也是完全没有然,要读游戏描述也是完全没有问题的,如图问题的,如图10-2所示。所示。图10-2 读取游取游戏描述描述 App爬虫可以实现自动滚动屏幕,自动单击进入详情页。凡是人爬虫可以实现自动滚动屏幕,自动单击进入详情
6、页。凡是人可以对手机进行的操作,可以对手机进行的操作,App爬虫都可以进行。爬虫都可以进行。UiAutomator是是Google官方提供的官方提供的Android自动化图形接口测试框自动化图形接口测试框架。通过它可以实现对架。通过它可以实现对Android设备屏幕的各种操作,或者直接从屏设备屏幕的各种操作,或者直接从屏幕上读取文字幕上读取文字。大部大部分系统版本大于分系统版本大于4.1的的Android系统,都会内置系统,都会内置UiAutomator。小米手机原装的小米手机原装的MIUI系统除外,系统除外,MIUI系统系统UiAutomator被移除了,需被移除了,需要刷开发版或者换其他系
7、统才能使用。要刷开发版或者换其他系统才能使用。10.1.1 10.1.1 环境搭建环境搭建1安装安装JRE 要使用要使用UiAutomator操作操作Android手机,首先需要在手机,首先需要在计算机上安算机上安装装Android的的软件开件开发工具包(工具包(Software Development Kit,SDK)。要)。要安装安装Android SDK,首先需要安装,首先需要安装Java运行运行时环境(境(Java Runtime Environment,JRE)。)。对于于Mac OS,使用,使用Homebrew安装安装Java开开发套件(套件(Java SE Development
8、 Kit,JDK)。)。JRE包含在了包含在了JDK里面:里面:brewupdatebrewcaskinstalljava 对于于Ubuntu,使用如下命令直接安装,使用如下命令直接安装JRE:sudoapt-getupdatesudoapt-getinstalldefault-jre 对于对于Windows,可以访问,可以访问http:/ 首先首先选择“Accept License Agreement”单选按按钮才能下才能下载 2安装安装AndroidSDK 安装安装完成完成JRE以后,再来安装以后,再来安装AndroidSDK。请打开。请打开https:/ 在网在网页最下面下最下面下载系系
9、统对应的的Android SDK 在在MacOS与与Ubuntu的终端输入并执行如下命令,如图的终端输入并执行如下命令,如图10-5所所示。示。cd/book/sdkbin/sdkmanagerplatform-tools图10-5 执行命令安装行命令安装platform-tools Windows系统直接在系统直接在tools文件夹中打开文件夹中打开CMD窗口,并输入窗口,并输入命令:命令:bin/sdkmanager.exeplatform-tools 输入输入完成命令并按完成命令并按Enter键,可以看到在终端窗口弹出安装键,可以看到在终端窗口弹出安装协议,输入协议,输入y并按并按Ent
10、er键即可安装键即可安装“platform-tools”。需要需要注意的是,这里执行这个命令时,程序会从注意的是,这里执行这个命令时,程序会从Google获取一获取一些数据,此时可能会由于网络问题导致失败。如果遇到网络问题,些数据,此时可能会由于网络问题导致失败。如果遇到网络问题,那么就需要使用能访问那么就需要使用能访问Google的代理,并且命令也需要做一些修改,的代理,并且命令也需要做一些修改,修改为:修改为:bin/sdkmanager.exeplatform-tools-proxy=http-proxy_host=代理代理IP-proxy-port=代理端口代理端口 安装安装完成以后,
11、会在完成以后,会在“/book/sdk”文件夹或者文件夹或者“E:ProgramFilessdksdk”文件夹下出现一个文件夹下出现一个“platform-tools”文件夹。现在需文件夹。现在需要将要将tools文件夹和文件夹和platform-tools文件夹添加到系统的环境变量中。文件夹添加到系统的环境变量中。3设置环境变量设置环境变量 对于对于使用使用MacOS或或Ubuntu系统并安装了系统并安装了zsh和和Oh-my-zsh的读者,的读者,请打开请打开/.zshrc并检查是否已经有并检查是否已经有exportPATH开头的一句话,如果有,开头的一句话,如果有,请修改为下面所示的代码
12、这样,其中的请修改为下面所示的代码这样,其中的tools和和platform-tools文件夹文件夹的地址请改为实际地址:的地址请改为实际地址:exportPATH=/Users/kingname/book/sdk/platform-tools:/Users/kingname/book/sdk/tools:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin 如果如果是是MacOS或者或者Ubuntu系统且没有安装系统且没有安装zsh和和Oh-my-zsh的读者,或者想临时添加环境变量进行测试,可直接在终端执行的读者,或者想临时添加环境变量进行测试,可直接在
13、终端执行下面代码,将下面代码,将tools和和platform-tools的地址改为实际地址:的地址改为实际地址:export PATH=$PATH:/Users/kingname/book/sdk/platform-tools:/Users/kingname/book/sdk/tools 需要需要注意的是,这种方法是临时添加环境变量,当前的终注意的是,这种方法是临时添加环境变量,当前的终端窗口不能关闭。一旦关闭再重新打开,就需要再一次执行上面端窗口不能关闭。一旦关闭再重新打开,就需要再一次执行上面的代码。的代码。对于对于Windows,打开任意一个文件夹,并在左侧导航窗口中,打开任意一个文件
14、夹,并在左侧导航窗口中右键单击右键单击“计算机计算机”,选择,选择“属性属性”命令,打开属性面板。在属命令,打开属性面板。在属性面板左侧选择性面板左侧选择“高级系统设置高级系统设置”选项,进入选项,进入“高级高级”选项卡,选项卡,最后单击右下角的最后单击右下角的“环境变量环境变量”按钮进入按钮进入“环境变量环境变量”对话框,对话框,如图如图10-6所示。所示。图10-6 单击“环境境变量量”按按钮 4开启开发者模式开启开发者模式 要要通过计算机控制手机,还需要打开通过计算机控制手机,还需要打开Android手机的开发者手机的开发者模式。本书以小米手机的模式。本书以小米手机的MIUI开发版和开发
15、版和Android原生系统为例来原生系统为例来演示如何开启开发者模式。演示如何开启开发者模式。对于对于小米手机小米手机MIUI开发版,依次进入开发版,依次进入“系统设置系统设置”-“我的我的设备设备”-“全部参数全部参数”,快速连续单击,快速连续单击“MIUI版本版本”这一栏这一栏5次,次,开发者模式就会打开。打开以后,回到开发者模式就会打开。打开以后,回到“系统设置系统设置”主界面,依主界面,依次进入次进入“更多设置更多设置”-“开发者选项开发者选项”。在。在“开发者选项开发者选项”中分中分别打开别打开“USB调试调试”、“USB安装安装”和和“USB调试(安全模式)调试(安全模式)”这几个
16、开关,系统会弹出警告,选择允许。这几个开关,系统会弹出警告,选择允许。图10-7 双双击“Path”并添加并添加tools文件文件夹 对于对于Andorid原生系统,以原生系统,以Google生产的生产的Nexus为例。打开为例。打开“系系统设置统设置”,进入最下方的,进入最下方的“系统系统”,打开系统信息界面。拖动最下,打开系统信息界面。拖动最下方,找到方,找到“关于手机关于手机”并点击,进入手机状态界面,如图并点击,进入手机状态界面,如图10-8所示。所示。快速快速单击单击“版本号版本号”5次,打开开发者选项。次,打开开发者选项。开发开发者选项打开以后,就可以在手机信息界面找到进入开发者者
17、选项打开以后,就可以在手机信息界面找到进入开发者选项的入口了,如图选项的入口了,如图10-9所示。所示。进入进入开发者选项的设置页面,打开开发者选项的设置页面,打开“USB调试调试”,如图,如图10-10所所示。示。图10-8 手机状手机状态界面界面图10-9 开开发者者选项入口出入口出现在系在系统设置中置中图10-10 在开在开发者者选项中打开中打开USB调试开关开关 由于由于各大厂商对各大厂商对Android系统几乎都有自己的定制化,因此不系统几乎都有自己的定制化,因此不能在这里一能在这里一一列举所有型号手机开启开发者模式的操作。对于没一列举所有型号手机开启开发者模式的操作。对于没有提及的
18、手机型号,请通过网络搜索。有提及的手机型号,请通过网络搜索。设置设置好环境变量以后,在终端窗口输入好环境变量以后,在终端窗口输入“uiautomatorviewer”并按并按Enter键,如果可以弹出图键,如果可以弹出图10-11所示所示的的UIAutomatorViewer窗口,表明环境设置成功。窗口,表明环境设置成功。将将Android手机连接到计算机上,保持手机连接到计算机上,保持手机屏幕为亮起状态,单击手机屏幕为亮起状态,单击UIAutomatorViewer左上角文件夹右侧的手机图标,如左上角文件夹右侧的手机图标,如果能够看到手机屏幕出现在窗口中,则表果能够看到手机屏幕出现在窗口中,
19、则表示一切顺利,环境搭建成功完成。如果在示一切顺利,环境搭建成功完成。如果在这个过程中手机弹出了任何警告窗口,都这个过程中手机弹出了任何警告窗口,都选择选择“运行运行”或者或者“确定确定”。图10-11 UI Automator Viewer 窗口窗口10.1.2 10.1.2 使用使用Python Python 操纵手机操纵手机 要使用要使用Python来操作来操作UI Automator从而控制手机,需要安装一个第三方从而控制手机,需要安装一个第三方库。这个个库的名字就是的名字就是uiautomator,使,使用用pip进行安装,如行安装,如图10-12所示。所示。图10-12 使用使用p
20、ip安装安装uiautomator 安装安装完成以后运行完成以后运行Python并导入并导入uiautomator:fromuiautomatorimportDevice device=Device()print(device.dump()由于由于是第一次运行,是第一次运行,uiautomator会往手机中安装两个没有图会往手机中安装两个没有图标的程序。有一些手机系统可能会弹出窗口询问是否允许安装,标的程序。有一些手机系统可能会弹出窗口询问是否允许安装,单击单击“继续安装继续安装”按钮,如图按钮,如图10-13所示所示。图10-13 系系统询问是否安装,是否安装,单击“继续安装安装”按按钮 安
21、装安装完成以后,可以看到完成以后,可以看到终端窗口出现了类似于终端窗口出现了类似于XML的的内容,如图内容,如图10-14所示。这说明所示。这说明uiautomator这个第三方库成功这个第三方库成功安装。此时就可以使用安装。此时就可以使用Python控制手机了。控制手机了。图10-14 终端窗口出端窗口出现了了类似于似于XML的内容的内容 有有一点需要特别说明,一点需要特别说明,UIAutomatorViewer与与Pythonuiautomator不不能同时使用。一旦能同时使用。一旦Python的的uiautomator运行过一次,它安装的两个文件运行过一次,它安装的两个文件就会在手机后台
22、运行就会在手机后台运行。这这两个文件会占用两个文件会占用Android内部的一个叫作内部的一个叫作UIhierarchy的东西,从而的东西,从而导致导致SDK自带的自带的UIAutomatorViewer一旦尝试获取手机屏幕就会报错,如一旦尝试获取手机屏幕就会报错,如图图10-15所示。所示。图10-15 一旦运行一旦运行过uiautomator,就会,就会导致致SDK自自带的的UI Automator Viewer不能不能获取手机屏幕取手机屏幕 与与Selenium一样,要操作手机上一样,要操作手机上面的元素,首先要找到被操作的东西。面的元素,首先要找到被操作的东西。以打开微信为例,首先翻到
23、有微信的以打开微信为例,首先翻到有微信的那一页,如图那一页,如图10-16所示。所示。图图10-16 翻到有微信的一页翻到有微信的一页 编写编写如下代码:如下代码:fromuiautomatorimportDevice device=Device()device(text=微信微信).click()运行运行以后可以看到,微信自动被点击并打开。以后可以看到,微信自动被点击并打开。如果如果计算机上面只连接了一台计算机上面只连接了一台Android手机,那么初始化设备手机,那么初始化设备连接只需要使用连接只需要使用device=Device()即可。那么如果计算机上连接了即可。那么如果计算机上连接了
24、很多台手机,该怎么办呢?此时就需要指定手机的串号。要查看很多台手机,该怎么办呢?此时就需要指定手机的串号。要查看手机串号,需要在终端输入以下命令:手机串号,需要在终端输入以下命令:adb devices-ladb devices-l 从从输出的内容可以看到手机的串号,如图输出的内容可以看到手机的串号,如图10-17所示。所示。图10-17 使用命令使用命令查询手机串号手机串号10.1.3 10.1.3 选择器选择器 如何知道有哪些如何知道有哪些选择器可供使用呢?器可供使用呢?请执行以下代行以下代码:from uiautomator import Devicedevice=Device()pri
25、nt(device.dump()此此时终端会以端会以XML输出当前手机屏幕出当前手机屏幕显示的窗口布局信息,如示的窗口布局信息,如图10-18所示。所示。这里这里的的XML就相当于网页中的就相当于网页中的HTML,用来描述窗口上面各个部,用来描述窗口上面各个部分的布局信息。分的布局信息。XML的格式与的格式与HTML非常像,格式为:非常像,格式为:文本文本 可以可以用一个标签来作为选择器,用一个标签来作为选择器,也可以同时使用多个标签来更精确也可以同时使用多个标签来更精确地描述某一个元素。一般来说,操地描述某一个元素。一般来说,操作一个有文字的元素,主要是使用作一个有文字的元素,主要是使用te
26、xt这个属性;如果是从屏幕上读文这个属性;如果是从屏幕上读文字,就使用其他的属性。字,就使用其他的属性。图10-18 当前当前手机屏幕手机屏幕显示的窗口示的窗口布局信息布局信息10.1.4 10.1.4 操作操作 在在选择好元素以后,就需要好元素以后,就需要对它它进行操作。最常行操作。最常见的操作的操作如下:如下:l获得屏幕文字;得屏幕文字;l滚动屏幕;屏幕;l滑滑动屏幕;屏幕;l点点击屏幕;屏幕;l输入文字;入文字;l判断元素是否存在;判断元素是否存在;l点亮关点亮关闭屏幕;屏幕;l操作操作实体按键实体按键;lwatcher。1获得屏幕文字获得屏幕文字 如果如果要从要从Android手机上读
27、取当前屏幕上显示的文本内容,用到手机上读取当前屏幕上显示的文本内容,用到的是一个元素的的是一个元素的“.text”属性。这里以获取游戏商场类属性。这里以获取游戏商场类App“TapTap”当前屏幕的游戏名称为例。当前屏幕的游戏名称为例。当前当前手机上的手机上的TapTap界面如图界面如图10-19所示。所示。从从屏幕上可以看到有屏幕上可以看到有3个游戏的名字,分别是个游戏的名字,分别是“霍基霍基2”“”“yellow”和和“我的星球我的星球”。现在的目的是要把这。现在的目的是要把这3个名字读取下来。首先使用个名字读取下来。首先使用以下代码获取当前屏幕的以下代码获取当前屏幕的XML布局,如图布局
28、,如图10-20所示。所示。图10-19 TapTap首首页 图10-20 TapTap首首页对应的的XML布局布局 从从这个布局可以看到,所有标题的这个布局可以看到,所有标题的resource-id都是都是“com.taptap:id/bottom_app_name”。如果需要获取第一个游戏。如果需要获取第一个游戏“霍霍基基2”的名字,可以使用下面这一行代码:的名字,可以使用下面这一行代码:game_1_title=device(resourceId=com.taptap:id/bottom_app_name).text 运行运行结果如图结果如图10-21所示。所示。图10-21 获取第一个
29、游取第一个游戏的名称的名称 但但实际上,当前屏幕有实际上,当前屏幕有3个游戏,它们的个游戏,它们的resource-id都是相同的。都是相同的。如何把如何把3个游戏的名字都获取下来呢?方法很简单,那就是个游戏的名字都获取下来呢?方法很简单,那就是“先别急先别急着获取着获取.text属性属性先寻找元素,再用先寻找元素,再用for循环展开,最后再获循环展开,最后再获取取.text属性属性”。其代码如下。其代码如下。game_title_list=game_title_list=device(resourceId=com.taptap:id/bottom_app_name)device(resour
30、ceId=com.taptap:id/bottom_app_name)for title in game_title_list:for title in game_title_list:print(title.text)print(title.text)运行运行结果如图结果如图10-22所示。所示。图10-22 同同时获取当前屏幕的取当前屏幕的3个游个游戏名名 2滚动屏幕滚动屏幕 滚动滚动屏幕对应的操作为屏幕对应的操作为“.scroll()”。它的操作对象是一。它的操作对象是一个可以滚动的对象。如果手动操作可以把屏幕向上滚动,那么屏个可以滚动的对象。如果手动操作可以把屏幕向上滚动,那么屏幕上应
31、该至少有一个元素是可以滚动的,因此选择器可以写为:幕上应该至少有一个元素是可以滚动的,因此选择器可以写为:device(scrollable=True)那么那么向上滚动一屏可以写为:向上滚动一屏可以写为:device(scrollable=True).scroll.vert.forward()如果如果想向下滚动一屏,则需要把想向下滚动一屏,则需要把forward()换为换为backward():device(scrollable=True).scroll.vert.forward()由于由于向上、向下是向上、向下是“垂直方向垂直方向”,所以代码中使用了,所以代码中使用了vert,这是,这是英语
32、单词英语单词vertical(垂直的)的简写。可能有些(垂直的)的简写。可能有些App会出现左右滚动的会出现左右滚动的情况,这时候就需要使用情况,这时候就需要使用horiz,这是英语单词,这是英语单词horizontal(水平的)(水平的)的简写。于是,向左及向右滚动就可以写为:的简写。于是,向左及向右滚动就可以写为:device(scrollable=True).scroll.horiz.forward()#device(scrollable=True).scroll.horiz.forward()#向右滚动向右滚动 device(scrollable=True).scroll.horiz.
33、backward()#device(scrollable=True).scroll.horiz.backward()#向左滚动向左滚动 使用使用滚动屏幕的方式,就可以把所有游戏的名字都读取下来,滚动屏幕的方式,就可以把所有游戏的名字都读取下来,如图如图10-23所示。所示。图10-23 滚动屏幕屏幕获取所有游取所有游戏名称名称 有有一点需要注意,由于滚动一屏时,有可能前一屏最下面一点需要注意,由于滚动一屏时,有可能前一屏最下面的元素滚动以后刚好到了后一屏的最上面,因此可能出现重复获的元素滚动以后刚好到了后一屏的最上面,因此可能出现重复获取同一个游戏名字两次的情况,如图取同一个游戏名字两次的情况
34、,如图10-23中的方框所示。在实中的方框所示。在实际使用时要注意去重处理。际使用时要注意去重处理。3滑动屏幕滑动屏幕 在在某些情况下,整个窗口布局的某些情况下,整个窗口布局的XML里面,所有元素的里面,所有元素的scrollable属性值全部都是属性值全部都是False,例如小米手机的桌面。在这种情况下,没有办,例如小米手机的桌面。在这种情况下,没有办法使用法使用“scrollable=True”来左右滚动桌面,于是就需要使用根据坐来左右滚动桌面,于是就需要使用根据坐标来滑动桌面的标来滑动桌面的“.swipe()”方法。方法。在在Android系统的屏幕上,左上角为坐标原点系统的屏幕上,左上
35、角为坐标原点(0,0),越向下,越向下,y轴轴数字越大;越向右,数字越大;越向右,x轴数字越大。轴数字越大。“.swipe()”这个方法操作的对象是整个手机屏幕,所以不需要这个方法操作的对象是整个手机屏幕,所以不需要为为device设定选择器。设定选择器。“.swipe()”的用法为:的用法为:device.swipe(400,600,0,600)device.swipe(400,600,0,600)它它接收接收4个参数,分别为起始点个参数,分别为起始点x坐标,起始点坐标,起始点y坐标,终点坐标,终点x坐标,终点坐标,终点y坐标。对于左右滑动来说,只需要改变坐标。对于左右滑动来说,只需要改变x
36、坐标即可。坐标即可。如果要显示右边的一屏,那么起始点的如果要显示右边的一屏,那么起始点的x坐标要大于终点的坐标要大于终点的x坐标。坐标。如果要显示左边的一屏,起始点的如果要显示左边的一屏,起始点的x坐标要小于终点的坐标要小于终点的x坐标。坐标。如果如果在实际写代码的时候搞不清在实际写代码的时候搞不清x坐标哪个大,就亲自把手坐标哪个大,就亲自把手放在屏幕上滑动进行查看。如果要显示右边的一屏,那么会首先放在屏幕上滑动进行查看。如果要显示右边的一屏,那么会首先把手放在屏幕右侧,按住然后往左移动,所以此时起始点的把手放在屏幕右侧,按住然后往左移动,所以此时起始点的x坐坐标要大一些。标要大一些。4点击屏
37、幕点击屏幕 选择选择一个元素以后,除了获取它上面的文字外,还可以点击。就一个元素以后,除了获取它上面的文字外,还可以点击。就如同前面通过点击打开微信一样。点击操作如同前面通过点击打开微信一样。点击操作“.click()”和和“.long_click()”分别对应短按点击和长按点击,它们可以直接应用分别对应短按点击和长按点击,它们可以直接应用于一个被选择出来的元素上。例如:于一个被选择出来的元素上。例如:device(text=微信微信).click()device(text=微信微信).long_click()点击点击操作也可以直接应用于坐标位置。例如:操作也可以直接应用于坐标位置。例如:de
38、vice.click(230,567)#device.click(230,567)#第第1 1个参数为横坐标个参数为横坐标x x轴,第轴,第2 2个参数个参数为纵坐标为纵坐标y y轴轴 device.long_click(230,567)#device.long_click(230,567)#第第1 1个参数为横坐标个参数为横坐标x x轴,第轴,第2 2个参数为纵坐标个参数为纵坐标y y轴轴 在在某些某些App中,可能某一个元素并没中,可能某一个元素并没有一个独特的标志来让选择器选择。这个有一个独特的标志来让选择器选择。这个时候就可以直接使用坐标来操作。时候就可以直接使用坐标来操作。以以Tap
39、Tap的搜索按钮为例,搜索按钮的搜索按钮为例,搜索按钮的坐标如图的坐标如图10-24所示。所示。图10-24 TapTap搜索按搜索按钮的坐的坐标 对于对于这个按钮,在右侧信息窗口中可以看到这个按钮,在右侧信息窗口中可以看到“ImageButton640,80688,128”中的中的640,80对应了这个搜索按钮的对应了这个搜索按钮的左上角的坐标,左上角的坐标,688,128对应了搜索按钮右下角的坐标。对于一个矩形对应了搜索按钮右下角的坐标。对于一个矩形来说,确定了一对对角的坐标,也就确定了来说,确定了一对对角的坐标,也就确定了4个角的坐标。因此,只要点个角的坐标。因此,只要点击这两个坐标之间
40、的位置,就等于点击了这个搜索按钮。击这两个坐标之间的位置,就等于点击了这个搜索按钮。为为保险和准确起见,可以点击这个搜索按钮矩形的正中心位置,也保险和准确起见,可以点击这个搜索按钮矩形的正中心位置,也就是就是664,104。那么代码就可以写成:。那么代码就可以写成:device.click(664,104device.click(664,104)当然当然还有一种更简单的办法,那还有一种更简单的办法,那就是把就是把UiAutomatorViewer的窗口拉的窗口拉大一些,将鼠标指针在屏幕上面随意大一些,将鼠标指针在屏幕上面随意移动,就可以直接看到鼠标指针当前移动,就可以直接看到鼠标指针当前位置的
41、坐标,如图位置的坐标,如图10-25所示。所示。图10-25 箭箭头指向当前鼠指向当前鼠标指指针所所在位置的坐在位置的坐标 5输入文字输入文字 既然既然进入了搜索界面,那就需要进入了搜索界面,那就需要搜索内容了。输入文本使用的操作是搜索内容了。输入文本使用的操作是“.set_text()”。TapTap的搜素框对的搜素框对应的应的resource-id为为“com.taptap:id/input_box”,如图,如图10-26所示。所示。图10-26 搜索框搜索框对应的的resource_id 因此因此可以用这个可以用这个resource-id来作为选择器定位到搜索框,再来作为选择器定位到搜索
42、框,再输入文本输入文本。例如例如搜索名为搜索名为“汉家江湖汉家江湖”的游戏,那么就使用以下代码:的游戏,那么就使用以下代码:device(resourceId=com.taptap:id/input_box).set_text(汉家江湖汉家江湖)6判断元素是否存在判断元素是否存在 由于由于手机上面的各个元素加载是需要一定时间的,如果在元素手机上面的各个元素加载是需要一定时间的,如果在元素加载出来之前就对其进行操作,就会导致程序报错,如图加载出来之前就对其进行操作,就会导致程序报错,如图10-27所示。所示。这是因为不存在一个这是因为不存在一个resource-id为为“com.taptap:i
43、d/input_box33”的元素。的元素。在在操作一个元素之前,先判断一下它是否存在是比较明智的操作一个元素之前,先判断一下它是否存在是比较明智的做法。判断元素是否存在,使用做法。判断元素是否存在,使用“.exists”属性。如果存在,属性。如果存在,值为值为True,否则为,否则为False。其用法为:。其用法为:input_box=device(resourceId=com.taptap:id/input_box)input_box=device(resourceId=com.taptap:id/input_box)if input_box.exists:if input_box.exi
44、sts:input_box.set_text(input_box.set_text(汉家江湖汉家江湖)else:print(搜索框不存在搜索框不存在)图10-27 操作一个不存在的元素操作一个不存在的元素导致程序致程序报错 7点亮关闭屏幕点亮关闭屏幕 使用使用“.wakeup()”方法和方法和“.sleep()”方法可以点亮或者方法可以点亮或者关闭屏幕。当手机屏幕处于关闭状态时,使用关闭屏幕。当手机屏幕处于关闭状态时,使用“.wake()”方法方法可以让屏幕点亮;当手机屏幕处于点亮状态时,使用可以让屏幕点亮;当手机屏幕处于点亮状态时,使用“.sleep()”方法可以将其关闭。其用法为:方法可以
45、将其关闭。其用法为:device.wakeup()#device.wakeup()#点亮屏幕点亮屏幕 device.sleep()#device.sleep()#关闭屏幕关闭屏幕 8操作实体按键操作实体按键 Android一般自带不少实体按键,使用一般自带不少实体按键,使用Python的的uiautomator可以模拟这些按键被按下的状态。其使用方法为:可以模拟这些按键被按下的状态。其使用方法为:device.press.device.press.实体按键名称实体按键名称()()常见常见的实体按键名称和作用如表的实体按键名称和作用如表10-1所示。所示。实体按体按键名称名称作用作用power电
46、源源键back返回返回键menu菜菜单键volume_up音量增大音量增大volume_down音量减小音量减小home返回桌面返回桌面表表10-1 常常见的的实体按体按键名称和作用名称和作用 9watcher 使用使用Android手机的时候,经常会遇到这样的情况:手机用着手机的时候,经常会遇到这样的情况:手机用着用着,突然弹出一个对话框,提示当前用着,突然弹出一个对话框,提示当前App有新版本可用。对于有新版本可用。对于用户来说,遇到这种对话框,又不想升级,那么按一下返回键就用户来说,遇到这种对话框,又不想升级,那么按一下返回键就可以暂时把这个对话框关闭。但是这种对话框对于使用程序来操可以
47、暂时把这个对话框关闭。但是这种对话框对于使用程序来操作手机的场景来说,就是一个灾难。作手机的场景来说,就是一个灾难。假设假设现在有几百个游戏,需要通过现在有几百个游戏,需要通过TapTap搜索它们,并获取搜索它们,并获取它们的下载量。正常的流程应该是下面这样。它们的下载量。正常的流程应该是下面这样。(1)初始位置:搜索框。)初始位置:搜索框。(2)清空搜索框原有的文字。)清空搜索框原有的文字。(3)输入游戏名字。)输入游戏名字。(4)点击搜索按钮。)点击搜索按钮。(5)点击第)点击第1个搜索结果进入游戏详情页。个搜索结果进入游戏详情页。(6)从游戏详情页获取下载量。)从游戏详情页获取下载量。(
48、7)点击实体按键)点击实体按键back返回搜索界面。返回搜索界面。(8)转到步骤()转到步骤(1)。)。图图10-28 假设手机屏幕当前在详情页假设手机屏幕当前在详情页 在在正常情况下,可以按照从(正常情况下,可以按照从(1)()(8)的顺序循环往复,)的顺序循环往复,直到搜索完所有的游戏。但是如果在第(直到搜索完所有的游戏。但是如果在第(6)步获取了下载量以后,)步获取了下载量以后,突然弹出了升级提示框突然弹出了升级提示框。此时此时由于程序不知道弹出了框,它还在执行第(由于程序不知道弹出了框,它还在执行第(7)步,按)步,按下了返回键下了返回键。此时此时仅仅是关闭了升级提示的对话框,手机屏幕
49、仍然还处于仅仅是关闭了升级提示的对话框,手机屏幕仍然还处于游戏的详情页,但是程序以为已经返回了搜索界面,于是尝试操游戏的详情页,但是程序以为已经返回了搜索界面,于是尝试操作搜索框。可是在详情页根本就没有搜索框,于是就会导致程序作搜索框。可是在详情页根本就没有搜索框,于是就会导致程序报错。报错。这种情况当然可以使用这种情况当然可以使用exists来判断搜索框是否存在。但问来判断搜索框是否存在。但问题在于,即使知道了搜索框不在,却并不能解决该问题。因为根题在于,即使知道了搜索框不在,却并不能解决该问题。因为根本原因在于手机屏幕和程序出现了不同步,要解决问题,就需要本原因在于手机屏幕和程序出现了不同
50、步,要解决问题,就需要让它们同步。让它们同步。使用使用watcher可以让程序在找不到元素时自动尝试解决问题。可以让程序在找不到元素时自动尝试解决问题。假设目前手机屏幕所在的界面为详情页,如图假设目前手机屏幕所在的界面为详情页,如图10-28所示。所示。10其他操作其他操作 Android的的UIAutomator框架可以实现所有图形界面的操作,框架可以实现所有图形界面的操作,只要是人能做的它都能做。只要是人能做的它都能做。Python的的uiautomator库完整实现了库完整实现了这些操作。但是由于一些操作对于开发爬虫来说并没有什么作用,这些操作。但是由于一些操作对于开发爬虫来说并没有什么