IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> App数据抓取(Appium使用) -> 正文阅读

[开发测试]App数据抓取(Appium使用)

Android开发工具

  • 有些APP需要反编译破解加密算法,对于加固的还要脱壳
  • 我们需要从Android SDK获取一些支持,安装步骤
    • JDK8,百度查看安装步骤,一定要配置环境变量
      app30
      • 偷偷备注:我放在E盘
    • 下载安卓SDK并安装,链接,记得设置环境变量(下图给出的是参考,别当真)
      • 官方推荐的是下载带SDK的Android Studio,但我们在配合Appium时只需SDK
        app5
        在这里插入图片描述

      • 官方推荐的没几个好东西,谁?谁说的?

      • 注:如果按照上面那个链接下载的,adb等工具也一起点它下面链接下载!!!

    • 打开SDK
      • 设置代理,然后package/reload
        app2
      • 选择要安装的包:
        app4
        app5
    • 等待下载完这些SDK的工具即可!

adb调试工具

  • 先介绍第一个工具:Android Debug Bridge
  • 和模拟器中的adb一样,这里用来和模拟器交互,很重要
  • 在夜神模拟器中打开开发者模式和USB调试
    • 连续点击版本号
    • 返回设置,开发者选项,打开USB
    • 在cmd中查看adb version,连接的设备:adb devices
      app6
  • 解决和模拟器版本不匹配的问题
    app7
    • 一个.exe两个.dll文件组成的这个工具
      app6
    • 拷贝到模拟器的bin下,将其替换!
    • nox_adb.exe也换成SDK中的adb.exe,可以备份一下
    • 重启安卓模拟器
      app8
    • 你没看错,就是这个名字:127.0.0.1:62025
  • 好了好了,老师来了赶紧使用吧~
    • 用adb朝模拟器安装App:adb -s 127.0.0.1:62025 install 安装包位置
      app10
    • 传文件
      • 上传到模拟器:adb push 主机文件路径 /sdcard,sdcard是模拟器存储卡
      • 下载到主机:adb pull /sdcard/test.txt 主机路径
    • 截图:adb shell screencap /sdcard/capture.png

uiautomator

  • 分为两部分:uiautomatorviewer和uiautomator
    app11
  • uiautomatorviewer
    • Android SDK提供的一个图形界面工具,扫描和分析应用的UI控件,放在SDK/tools目录
    • 定位控件不就能获取里面的数据了嘛!类似网页定位元素(闪退问题?关了360啊!)
      app12
      app13
    • 上面是两个测试用的App,可以选一个你喜欢的App安装到模拟器试试
    • 当然,我们更常用的定位方法是获取控件的Xpath路径,可以升级automatorviewer就能获取xpath信息了
    • 升级需要的jar文件在哪里呢?你可以私我,要替换的文件有:
      app14
    • 双击tools/下的uiautomatorviewer.bat启动
    • 好了,看看有没有xpath信息吧!
    • uiautomator先放一放,接着看appium的inspector(录制)

appium详解

  • 自动化测试服务器,即可以通过配置它,自动操作APP,配合uiautomator定位控件,获取数据
    app31
    • 简而言之,它能配合脚本给App发送命令,获取Activity(页面),也可录制动作
      • 指令脚本,不是爬取脚本
    • 需要了解一些Android和iOS开发的基本知识
    • 现在都是再次封装的Appium Desktop,基础篇有讲过,它是作为服务器的,一般监听自己的0.0.0.0即可

inspector

  • 配置Android/iOS平台以及App信息,建立连接(与Bootstrap.jar通信)
  • 打开录制功能,可以生成所点击的控件的获取代码,后面即可自动重放这些操作,到指定的页面,再配合爬取脚本获取想要的数据
    • Desired Capability:配置Appium会话,告诉服务器想要自动化的平台和应用程序,使用配置文件:有很多配置,用到了再了解就好
      app33
    • 获取appPackage和appActivity的方法:
      • cmd运行adb shell,登录后执行logcat | grep cmp=即可看到
        app32
    • noReset是清除应用缓存
    • save as...后启动(如果报错,可能需要关掉adb shell啥的)
      app35
      • 有时应用可能会“停止运行”无法启动,appium出现问题,但是adb shell仍可以登录
    • 页面使用介绍:
      app36
    • 可以使用Send Keys将输入发送到界面的控件,App也会同步
    • 使用录制会得到操作控件的执行代码:(后面会用到)
      app37
    • 我们一般使用UIAutomatorViewer能获取更多控件信息,这就是自动化和SDK工具的结合使用了
    • uiautomatorviewer和appium是冲突的,记得先关闭appium
    • 如果想模拟第一次打开App,需要在模拟器设置中清除App数据缓存
  • 使用python脚本模拟滑动操作
    • 这里要配合python脚本了,在appium中Start Session即可,这里需要使用包:appium
      • 可以使用pip install Appium-Python-Client安装,或者在pycharm中Alt+Enter
      • 可以使用如下脚本查看是否能操作appium启动App
      from appium import webdriver
      
      param = {
          "platformName": "Android",
          "platformVersion": "5.1.1",
          "deviceName": "127.0.0.1:62025",
          "appPackage": "com.douguo.recipe",
          "appActivity": "com.douguo.recipe.HomeActivity",
          "noReset": True
      }
      
      driver = webdriver.Remote("http://localhost:4723/wd/hub",param)   # 4723是启动appium的端口,这里相当于操控appium
      
    • 使用uiautomatorviewer获取xpath路径,再结合python脚本执行相应操作:(先关闭appium)
      app38
    • 以上隐私条款,登录的用户名密码等操作,需要测试调整,加上必要的判断,使用了noReset参数,再次登录时会忽略前面的步骤,也需要修改代码调整
      from appium import webdriver
      from selenium.webdriver.support.ui import WebDriverWait
      import time
      
      
      def get_size():
          '''
          获取页面的宽高
          :return:
          '''
          width = driver.get_window_size()['width']
          height = driver.get_window_size()['height']
          return [width, height]
      
      
      def enter_slide(driver):
          '''
          进入要滑动的页面
          :param driver:
          :return:
          '''
          # 第一次启动App,点击“同意”“好的”
          # 再次启动不需要点击,所以加个判断
          try:
              # 等待3秒还没找到这个xpath都会pass,如果3秒内找到,会执行click
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.FrameLayout[@resource-id='com.douguo.recipe:id/agree_authorization']")):
                  driver.find_element_by_xpath(
                      "//android.widget.FrameLayout[@resource-id='com.douguo.recipe:id/agree_authorization']").click()
      
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.FrameLayout[@resource-id='com.douguo.recipe:id/agree_authorization']")):
                  driver.find_element_by_xpath(
                      "//android.widget.FrameLayout[@resource-id='com.douguo.recipe:id/agree_authorization']").click()
      
              # 跳过引导
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "// android.widget.ImageView[ @ resource - id = 'com.douguo.recipe:id/img_jump']")):
                  driver.find_element_by_xpath(
                      "// android.widget.ImageView[ @ resource - id = 'com.douguo.recipe:id/img_jump']").click()
          except:
              pass
      
          # 进入“我的”,登录
          if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
              "//android.widget.LinearLayout[@resource-id='com.douguo.recipe:id/tab_item_normal_4']/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.ImageView[1]")):
              driver.find_element_by_xpath(
                  "//android.widget.LinearLayout[@resource-id='com.douguo.recipe:id/tab_item_normal_4']/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.ImageView[1]").click()
      
          try:
              # 点击“手机号登录”——“账号密码登录”
              # //android.widget.TextView[@resource-id='com.douguo.recipe:id/mine_phone_login']
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.TextView[@resource-id='com.douguo.recipe:id/mine_phone_login']")):
                  driver.find_element_by_xpath(
                      "//android.widget.TextView[@resource-id='com.douguo.recipe:id/mine_phone_login']").click()
              # 必须等等再点击账号密码登录
              # //android.widget.TextView[@resource-id='com.douguo.recipe:id/action_todo']
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.TextView[@resource-id='com.douguo.recipe:id/action_todo']")):
                  driver.find_element_by_xpath(
                      "//android.widget.TextView[@resource-id='com.douguo.recipe:id/action_todo']").click()
      
              # 输入手机号密码
              # //android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_email']
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_email']")):
                  # 先点击
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_email']").click()
                  # 再输入
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_email']").send_keys(
                      "18600465658")
                  # 先点击
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_password']").click()
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_password']").send_keys(
                      "yr143364")
                  # 同意隐私条款
                  driver.find_element_by_xpath(
                      "//android.widget.ImageView[@resource-id='com.douguo.recipe:id/check_confirmation_clause']").click()
                  # 点击登录
                  driver.find_element_by_xpath(
                      "//android.widget.TextView[@resource-id='com.douguo.recipe:id/confirm']").click()
          except:
              pass
      
          try:
              # 如果之前登录退出,这里会显示:“继续使用此账号登录”
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.TextView[@resource-id='com.douguo.recipe:id/login_channel_text']")):
                  # 仍可以在此点击“手机号登录”,执行后续输入步骤
                  driver.find_element_by_xpath(
                      "//android.widget.TextView[@resource-id='com.douguo.recipe:id/login_channel_text']").click()  # 直接登录
      
              # 输入手机号密码
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.TextView[@resource-id='com.douguo.recipe:id/action_todo']")):
                  # 还要点击“账号密码登录”
                  driver.find_element_by_xpath(
                      "//android.widget.TextView[@resource-id='com.douguo.recipe:id/action_todo']").click()
      
              # 不加这个判断它不输入,可能是必须等等才行!程序执行太快
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_email']")):
                  # 先点击再输入
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_email']").click()
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_email']").send_keys(
                      "18600465658")
              if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
                  "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_password']")):
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_password']").click()
                  driver.find_element_by_xpath(
                      "//android.widget.EditText[@resource-id='com.douguo.recipe:id/login_edittext_password']").send_keys(
                      "yr143364")
                  # 同意隐私条款
                  driver.find_element_by_xpath(
                      "//android.widget.ImageView[@resource-id='com.douguo.recipe:id/check_confirmation_clause']").click()
                  # 点击登录
                  driver.find_element_by_xpath(
                      "//android.widget.TextView[@resource-id='com.douguo.recipe:id/confirm']").click()
          except:
              pass
      
          # 接下来进入我们指定的页面,模拟滑动
          print("done!")
      
      def slide(driver):
          '''
          进入豆果美食首页滑动
          :return:
          '''
          #
          if WebDriverWait(driver, 3).until(lambda x: x.find_element_by_xpath(
              "//android.widget.LinearLayout[@resource-id='com.douguo.recipe:id/tab_item_normal_0']/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.ImageView[1]")):
              # 仍可以在此点击“手机号登录”,执行后续输入步骤
              driver.find_element_by_xpath(
                  "//android.widget.LinearLayout[@resource-id='com.douguo.recipe:id/tab_item_normal_0']/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.ImageView[1]").click()  # 直接登录
      
          # 滑动的起点终点
          position = get_size()
          x1 = position[0]*0.5
          y1 = position[1]*0.75   # 从下方开始滑动
          y2 = position[1]*0.5    # 滑到中点
      
          while True:
              driver.swipe(x1, y1, x1, y2)
              time.sleep(1) # 间歇不停滑动
      
      if __name__ == '__main__':
          param = {
              "platformName": "Android",
              "platformVersion": "5.1.1",
              "deviceName": "127.0.0.1:62025",
              "appPackage": "com.douguo.recipe",
              "appActivity": "com.douguo.recipe.HomeActivity",  # com.douguo.recipe/.HomeActivity   MainActivity
              "noReset": True
          }
          # 清除App数据之后启动可能会遇到问题,暂时没有定位出原因,换成MainActivity可能会好!
      
          driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", param)  # 4723是启动appium的端口,这里相当于操控appium
      
          enter_slide(driver)
          slide(driver)
      

小结

  • 这里使用模拟器+Appium+uiautomatorviewer+python脚本实现了模拟滑动操作
  • 和上一篇requset配合fiddler找到路径并发起请求获取数据的方式不同,这套组件是后面实战经常用到的
  • 下一篇尝试抓取DY的数据,还会用到新的组件
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-07 00:07:16  更:2021-07-07 00:07:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 16:16:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码