Android开发工具
- 有些APP需要反编译破解加密算法,对于加固的还要脱壳
- 我们需要从Android SDK获取一些支持,安装步骤
- JDK8,百度查看安装步骤,一定要配置环境变量
- 下载安卓SDK并安装,链接,记得设置环境变量(下图给出的是参考,别当真)
- 打开SDK
- 设置代理,然后package/reload
- 选择要安装的包:
- 等待下载完这些SDK的工具即可!
adb调试工具
- 先介绍第一个工具:Android Debug Bridge
- 和模拟器中的adb一样,这里用来和模拟器交互,很重要
- 在夜神模拟器中打开开发者模式和USB调试
- 连续点击版本号
- 返回设置,开发者选项,打开USB
- 在cmd中查看
adb version ,连接的设备:adb devices - 解决和模拟器版本不匹配的问题
- 一个.exe两个.dll文件组成的这个工具
- 拷贝到模拟器的bin下,将其替换!
- 将
nox_adb.exe 也换成SDK中的adb.exe ,可以备份一下 - 重启安卓模拟器
- 你没看错,就是这个名字:
127.0.0.1:62025 - 好了好了,老师来了赶紧使用吧~
- 用adb朝模拟器安装App:
adb -s 127.0.0.1:62025 install 安装包位置 - 传文件
- 上传到模拟器:
adb push 主机文件路径 /sdcard ,sdcard是模拟器存储卡 - 下载到主机:
adb pull /sdcard/test.txt 主机路径 - 截图:
adb shell screencap /sdcard/capture.png
uiautomator
- 分为两部分:uiautomatorviewer和uiautomator
- uiautomatorviewer
- Android SDK提供的一个图形界面工具,扫描和分析应用的UI控件,放在SDK/tools目录
- 定位控件不就能获取里面的数据了嘛!类似网页定位元素(闪退问题?关了360啊!)
- 上面是两个测试用的App,可以选一个你喜欢的App安装到模拟器试试
- 当然,我们更常用的定位方法是获取控件的Xpath路径,可以升级automatorviewer就能获取xpath信息了
- 升级需要的jar文件在哪里呢?你可以私我,要替换的文件有:
- 双击tools/下的
uiautomatorviewer.bat 启动 - 好了,看看有没有xpath信息吧!
- uiautomator先放一放,接着看appium的inspector(录制)
appium详解
- 自动化测试服务器,即可以通过配置它,自动操作APP,配合uiautomator定位控件,获取数据
- 简而言之,它能配合脚本给App发送命令,获取Activity(页面),也可录制动作
- 需要了解一些Android和iOS开发的基本知识
- 现在都是再次封装的Appium Desktop,基础篇有讲过,它是作为服务器的,一般监听自己的0.0.0.0即可
inspector
- 配置Android/iOS平台以及App信息,建立连接(与Bootstrap.jar通信)
- 打开录制功能,可以生成所点击的控件的获取代码,后面即可自动重放这些操作,到指定的页面,再配合爬取脚本获取想要的数据
Desired Capability :配置Appium会话,告诉服务器想要自动化的平台和应用程序,使用配置文件:有很多配置,用到了再了解就好 - 获取appPackage和appActivity的方法:
- cmd运行
adb shell ,登录后执行logcat | grep cmp= 即可看到 noReset 是清除应用缓存save as... 后启动(如果报错,可能需要关掉adb shell啥的)
- 有时应用可能会“停止运行”无法启动,appium出现问题,但是adb shell仍可以登录
- 页面使用介绍:
- 可以使用
Send Keys 将输入发送到界面的控件,App也会同步 - 使用录制会得到操作控件的执行代码:(后面会用到)
- 我们一般使用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)
- 使用uiautomatorviewer获取xpath路径,再结合python脚本执行相应操作:(先关闭appium)
- 以上隐私条款,登录的用户名密码等操作,需要测试调整,加上必要的判断,使用了
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:
'''
try:
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:
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()
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")
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",
"noReset": True
}
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", param)
enter_slide(driver)
slide(driver)
小结
- 这里使用模拟器+Appium+uiautomatorviewer+python脚本实现了模拟滑动操作
- 和上一篇
requset 配合fiddler找到路径并发起请求获取数据的方式不同,这套组件是后面实战经常用到的 - 下一篇尝试抓取DY的数据,还会用到新的组件
|