基本需求:通过python代码自动打开指定app,并打开相关的内容,停留一段时间。
用到的工具
- jdk 1.8
- sdk
- adb工具(android debug bridge)
- uiautomaorviewer
顺序
- 安装 jdk、安卓sdk
- 设置环境变量(Android SDK 和 java的环境变量)设置环境变量(Android SDK 和 java的环境变量)
- 打开命令行打开命令行
- 启动adb服务器:adb start-server
- 启动adb服务器:adb start-server启动adb服务器:adb start-server
- 查看已连接的设备,获取设备名称:adb devices
- 通过adb 获取app包名和activity名称(通过代码打开时需要用到):通过adb 获取app包名和activity名称(通过代码打开时需要用到):
1) adb devices (获取设备名)
2) adb -s [设备名] shell (进入设备的shell环境)
3) dumpsys activity | grep mFocusedActivity (前台的app) - 通过升级版 uiautomaorviewer,查看控件名,获取控件Xpath名称。
- 通过 driver.find_element_by_xpath 获取组件,通过send_keys传值,通过click点击。 关键是要获取正确唯一稳定的id。 不管是xpath 、resource_id还是text。 xpath偶尔会不稳定,不知道为啥。
第一版
# iqiyi_test.py 第一版
# @Date: 2019-02-26 16:31:49
# 注意事项:
# 1.需要确保足够电量,不要弹出电量不足的框框(或者定位到该框框,点击关闭)
import time
from appium import webdriver
desired_caps_iqiyi={
"platformName": "Android",
"platformVersion": "5.1.1",
"deviceName": "172.16.18.43:5555",
"appPackage": "com.qiyi.video",
"appActivity": "org.qiyi.android.video.MainActivity",
"noReset": True,
"unicodeKeyboard":True,
"resetKeyboard":True
}
driver = webdriver.Remote("http://localhost:4723/wd/hub",desired_caps_iqiyi)
def iqiyi_tv_show(key_word,num_tag):
#在搜索框输入 完全匹配的关键词
if num_tag != 1:
driver.find_element_by_id("com.qiyi.video:id/brs").send_keys(key_word)
else:
driver.find_element_by_xpath("//android.widget.TextView[@resource-id='com.qiyi.video:id/eav']").send_keys(key_word)
#点击搜索框
driver.find_element_by_xpath("//android.widget.TextView[@resource-id='com.qiyi.video:id/eah']").click()
# 点击第一集 text 要修改源码支持 by_name
driver.find_element_by_name("1").click()
# time.sleep(5)
# 按顺序点击 第 2 3 4 集
driver.find_element_by_name("2").click()
# time.sleep(5)
driver.find_element_by_name("3").click()
# time.sleep(5)
driver.find_element_by_name("4").click()
# time.sleep(5)
# 返回搜索页面 开了会员就没有广告
try:
#广告页的返回
driver.find_element_by_xpath("//android.widget.TextView[@resource-id='com.qiyi.video:id/player_ads_back_pre_ad']").click()
except:
#视频播放页的返回
driver.find_element_by_xpath("//android.widget.ImageView[@resource-id='com.qiyi.video:id/player_piecemeal_layer_back']").click()
def iqiyi_movie(key_word):
#电影
driver.find_element_by_xpath("//android.widget.EditText[@resource-id='com.qiyi.video:id/brs']").send_keys(key_word)
driver.find_element_by_xpath("//android.widget.TextView[@resource-id='com.qiyi.video:id/eah']").click()
# 点击播放
driver.find_element_by_id("com.qiyi.video:id/button1").click()
time.sleep(5)
try:
# 广告页的返回
driver.find_element_by_id("com.qiyi.video:id/player_ads_back_pre_ad").click()
except:
# 视频播放页的返回
driver.find_element_by_id("com.qiyi.video:id/player_piecemeal_layer_back").click()
def main():
tv_show_names=['小女花不弃','独孤皇后','黄金瞳']
num_tag=1
for name in tv_show_names:
iqiyi_tv_show(name,num_tag)
num_tag+=1
movies_names=['灵魂摆渡黄泉','昼颜','狂龙伏妖']
for name in movies_names:
iqiyi_movie(name)
main()
第二版
# @Date: 2019-02-26 16:31:49
# 注意事项:
# 1.需要确保足够电量,不要弹出电量不足的框框(或者定位到该框框,点击关闭)
import time
from appium import webdriver
# import config
# from iqiyi_request_save import get_channel
# channel_dict = {"channel":"空"}
driver = ''
desired_caps_iqiyi={
"platformName": "Android",
"platformVersion": "5.1.1",
"deviceName": "172.16.18.43:5555",
"appPackage": "com.qiyi.video",
"appActivity": "org.qiyi.android.video.MainActivity",
"noReset": True,
"unicodeKeyboard":True,
"resetKeyboard":True
}
# 连接 app
def connect_open_app():
global driver
driver = webdriver.Remote("http://localhost:4723/wd/hub",desired_caps_iqiyi)
# 点击播放页的剧集
def click_episode_by_xpath(num):
try:
driver.find_element_by_xpath("//android.support.v7.widget.RecyclerView/android.support.v7.widget.RecyclerView[2]/android.widget.RelativeLayout["+num+"]").click()
except:
driver.find_element_by_xpath("//android.support.v7.widget.RecyclerView[@resource-id='com.qiyi.video:id/recycler']/android.widget.RelativeLayout["+num+"]").click()
# 点击播放页的剧集
def click_episode_by_name(num):
driver.find_element_by_name(str(num)).click()
# 从播放页返回搜索页
def back_to_search_page():
# 返回搜索页面 开了会员就没有广告
# global driver
try:
driver.find_element_by_id("com.qiyi.video:id/player_ads_back_pre_ad").click() #广告页的返回
except:
driver.find_element_by_id("com.qiyi.video:id/player_piecemeal_layer_back").click() #视频播放页的返回
def input_in_search_box(key_word):
try:
#com.qiyi.video:id/brs
driver.find_element_by_id("com.qiyi.video:id/brs").send_keys(key_word)
#com.qiyi.video:id/eah
driver.find_element_by_xpath("//android.widget.TextView[@resource-id='com.qiyi.video:id/eah']").click()
except:
driver.find_element_by_xpath("//android.widget.TextView[@resource-id='com.qiyi.video:id/eav']").send_keys(key_word)
driver.find_element_by_xpath("//android.widget.ImageView[@resource-id='com.qiyi.video:id/right_search_icon']").click()
def click_first_episode_by_name(num):
driver.find_element_by_name(num).click()
def iqiyi_playing_by_name(key_word,num_tag):
#在搜索框输入,并点击搜索 (完全匹配的关键词)
input_in_search_box(key_word)
time.sleep(5)
# 点击第一集 text 要修改源码支持 by_name
click_first_episode_by_name("1")
# time.sleep(5)
# 按顺序点击 第 2 3 4 集
for num in ["2","3","4"]:
click_episode_by_name(num)
# time.sleep(5)
# 返回搜索页面
back_to_search_page()
def iqiyi_movie(key_word):
#电影
#在搜索框输入,并点击搜索 (完全匹配的关键词)
input_in_search_box(key_word)
# 点击播放
driver.find_element_by_id("com.qiyi.video:id/button1").click()
time.sleep(5)
# 返回搜索页面
back_to_search_page()
def iqiyi_playing_by_box(key_word,num_tag):
#在搜索框输入,并点击搜索 (完全匹配的关键词)
input_in_search_box(key_word)
time.sleep(5)
# 点击第一集 text 要修改源码支持 by_name
click_first_episode_by_name("1")
# time.sleep(5)
# 按顺序点击 第 2 3 4 集
for num in ["2","3","4"]:
click_episode_by_xpath(num)
# time.sleep(5)
back_to_search_page()
def change_channel(channel):
f = open("request_data\\channel.txt", "w")
f.write(channel)
f.close()
def click_circle_in_channel(names,channel_names,click_func_name):
num_tag=1
# 修改txt文件中的频道名称
change_channel(channel_names)
for name in names:
click_func_name(name,num_tag)
num_tag+=1
time.sleep(5)
def main():
connect_open_app()
tv_show_names=['小女花不弃','独孤皇后','黄金瞳']
click_circle_in_channel(tv_show_names,"tv_show",iqiyi_playing_by_name)
time.sleep(5)
movies_names=['小女花不弃','独孤皇后','黄金瞳']
click_circle_in_channel(movies_names,"tv_show",iqiyi_movie)
time.sleep(5)
dongman_names=['贺少的闪婚暖妻','画江湖之不良人 第3季','热血女王']
click_circle_in_channel(children_names,"children",iqiyi_playing_by_name)
# dongman_names_guoman=['次元二Bi治']
# click_circle_in_channel(children_names,"children",iqiyi_playing_by_box)
documentary_names=['贺少的闪婚暖妻','画江湖之不良人 第3季','热血女王']
click_circle_in_channel(children_names,"children",iqiyi_playing_by_name)
variety_names=['贺少的闪婚暖妻','画江湖之不良人 第3季','热血女王']
click_circle_in_channel(children_names,"children",iqiyi_playing_by_name)
children_names_like_tvshow=['暴速合体','熊出没之探险日记2',,'名侦探柯南 普通话']
click_circle_in_channel(children_names_like_tvshow,"children",iqiyi_playing_by_name)
children_names=['小猪佩奇 第四季']
click_circle_in_channel(children_names,"children",iqiyi_playing_by_box)
info_names=['贺少的闪婚暖妻','画江湖之不良人 第3季','热血女王']
click_circle_in_channel(children_names,"children",iqiyi_playing_by_name)
original_names=['贺少的闪婚暖妻','画江湖之不良人 第3季','热血女王']
click_circle_in_channel(children_names,"children",iqiyi_playing_by_name)
entertainment_names=['贺少的闪婚暖妻','画江湖之不良人 第3季','热血女王']
click_circle_in_channel(children_names,"children",iqiyi_playing_by_name)
dongman_names=['贺少的闪婚暖妻','画江湖之不良人 第3季','热血女王']
# 立即播放
#图标 //android.widget.RelativeLayout/android.widget.LinearLayout[7]
#图标 //android.widget.RelativeLayout/android.widget.LinearLayout[7]
#文字 //android.widget.TextView[@text='立即播放']
#第一集 图标 //android.support.v7.widget.RecyclerView/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]
#第一集 图标 //android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[2]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]
#第二集 图标 //android.support.v7.widget.RecyclerView/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[2]/android.widget.LinearLayout[1]
#第三集 图标 //android.support.v7.widget.RecyclerView/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[3]/android.widget.LinearLayout[1]
#第四集 图标 //android.support.v7.widget.RecyclerView/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[4]/android.widget.LinearLayout[1]
#播放界面 返回图标 //android.widget.TextView[@resource-id='com.qiyi.video:id/player_ads_back_pre_ad']
#播放界面 第二集 //android.support.v7.widget.RecyclerView/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[2]/android.widget.ImageView[1]
#播放界面 第三集 //android.support.v7.widget.RecyclerView/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[3]/android.widget.ImageView[1]
#播放界面 第四集 //android.support.v7.widget.RecyclerView[@resource-id='com.qiyi.video:id/recycler']/android.widget.RelativeLayout[4]/android.widget.ImageView[1]
# webdriver.wait()
# iqiyi_request_save.py
# from mitmproxy import ctx
import time
from imp import reload
from handle_excel import save_data
channel = "null 22222"
def read_channel():
f = open("request_data\\channel.txt", "r")
channel = f.read()
print("read_channel:"+channel)
f.close()
return channel
#必须这么写
def request(flow):
scheme = flow.request.scheme
method = flow.request.method
host = flow.request.host
path = flow.request.path
headers = str(flow.request.headers)
query = str(flow.request.query)
timestamp_start = str(flow.request.timestamp_start)
if scheme =='http':
channel=read_channel()
li = [scheme,method,host,path,headers,query,timestamp_start,channel]
print(li)
save_data(li)
print("done:::"+host)
# handle_excel.py
# @Date: 2019-02-27 17:44:58
import pandas as pd
def save_data(li):
df = pd.DataFrame([li], columns=['scheme','method','host','path','headers','query','timestamp_start','channel'])
df.to_csv('request_data/data.csv', mode='a', header=False)
mitmproxy-env.bat 自动启动服务。。。
@echo off
start cmd /k "cd D:规则管理\autoget &d: "
rem mitmdump -p 8080 -s iqiyi_request_save.py
rem 命令1 & 命令2 & 命令3 ... (无论前面命令是否故障,照样执行后面)
rem 命令1 && 命令2 && 命令3....(仅当前面命令成功时,才执行后面)
rem 命令1 || 命令2 || 命令3.... (仅当前面命令失败时.才执行后面)