#Appium框架详解
Appium是移动端自动化测试的明星框架,支持iOS和Android平台,使用WebDriver协议。
#Appium基础配置
# Appium服务器配置
# 1. 启动Appium服务器
# appium --address 127.0.0.1 --port 4723 --session-override --log-timestamp --log-level info
# 2. Appium客户端配置
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
import time
class AppiumController:
"""Appium控制器 - 用于App自动化控制"""
def __init__(self, platform_name='Android', device_name='Android Emulator',
app_package=None, app_activity=None, remote_url='http://localhost:4723'):
self.platform_name = platform_name
self.device_name = device_name
self.app_package = app_package
self.app_activity = app_activity
self.remote_url = remote_url
self.driver = None
# 配置Appium选项
self.options = UiAutomator2Options() \
.platform_name(platform_name) \
.device_name(device_name) \
.auto_grant_permissions(True) \
.unicode_keyboard(True) \
.reset_keyboard(True) \
.no_reset(False) \
.full_reset(False)
if app_package:
self.options.app_package(app_package)
if app_activity:
self.options.app_activity(app_activity)
def connect(self):
"""连接到Appium服务器"""
try:
self.driver = webdriver.Remote(self.remote_url, options=self.options)
print(f"✅ Appium连接成功: {self.remote_url}")
return True
except Exception as e:
print(f"❌ Appium连接失败: {e}")
return False
def disconnect(self):
"""断开连接"""
if self.driver:
self.driver.quit()
print("🔌 Appium连接已断开")
def find_element(self, locator, timeout=10):
"""查找元素"""
try:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(self.driver, timeout)
element = wait.until(EC.presence_of_element_located(locator))
return element
except Exception as e:
print(f"❌ 查找元素失败: {e}")
return None
def tap_element(self, locator):
"""点击元素"""
element = self.find_element(locator)
if element:
element.click()
print("✅ 元素点击成功")
return True
return False
def send_keys(self, locator, text):
"""输入文本"""
element = self.find_element(locator)
if element:
element.clear()
element.send_keys(text)
print(f"✅ 输入文本: {text}")
return True
return False
# Appium高级操作示例
def appium_advanced_operations():
"""Appium高级操作演示"""
# 启动抖音APP的示例配置
controller = AppiumController(
app_package='com.ss.android.ugc.aweme',
app_activity='.splash.SplashActivity'
)
if controller.connect():
driver = controller.driver
# 等待应用加载
time.sleep(5)
# 获取屏幕尺寸
size = driver.get_window_size()
width, height = size['width'], size['height']
# 手势操作 - 向上滑动
start_x, start_y = width // 2, height * 3 // 4
end_x, end_y = width // 2, height // 4
# 执行滑动操作
driver.swipe(start_x, start_y, end_x, end_y, 1000)
print("📱 执行滑动操作")
# 获取页面源码
page_source = driver.page_source
print(f"📄 页面源码长度: {len(page_source)}")
# 获取当前Activity
current_activity = driver.current_activity
print(f"🎯 当前Activity: {current_activity}")
# 获取应用信息
app_info = {
'package': driver.current_package,
'activity': driver.current_activity,
'orientation': driver.orientation
}
print(f"📱 应用信息: {app_info}")
controller.disconnect()#Appium实战 - 抖音自动化脚本
from appium import webdriver
from appium.options.android import UiAutomator2Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import random
class DouyinAutomation:
"""抖音自动化控制类"""
def __init__(self, device_udid=None):
self.device_udid = device_udid
self.driver = None
self.setup_driver()
def setup_driver(self):
"""设置Appium驱动"""
options = UiAutomator2Options()
options.platform_name = 'Android'
options.app_package = 'com.ss.android.ugc.aweme'
options.app_activity = '.splash.SplashActivity'
options.auto_grant_permissions = True
options.unicode_keyboard = True
options.reset_keyboard = True
if self.device_udid:
options.udid = self.device_udid
try:
self.driver = webdriver.Remote('http://localhost:4723', options=options)
print("✅ 抖音自动化驱动初始化成功")
except Exception as e:
print(f"❌ 驱动初始化失败: {e}")
def wait_for_element(self, locator, timeout=10):
"""等待元素出现"""
try:
wait = WebDriverWait(self.driver, timeout)
return wait.until(EC.presence_of_element_located(locator))
except:
return None
def scroll_feed(self, count=5):
"""滚动信息流"""
print(f"📱 开始滚动信息流,次数: {count}")
for i in range(count):
# 获取屏幕尺寸
size = self.driver.get_window_size()
width, height = size['width'], size['height']
# 滑动参数
start_x, start_y = width // 2, height * 3 // 4
end_x, end_y = width // 2, height // 4
# 执行滑动
self.driver.swipe(start_x, start_y, end_x, end_y, 1000)
# 随机等待
time.sleep(random.uniform(2, 4))
print(f" ✅ 第{i+1}次滑动完成")
def like_current_video(self):
"""点赞当前视频"""
# 寻找点赞按钮(这里使用常见的点赞按钮定位方式)
like_selectors = [
('id', 'com.ss.android.ugc.aweme:id/like_icon'),
('xpath', '//android.widget.ImageView[@content-desc="点赞"]'),
('xpath', '//android.widget.ImageView[contains(@resource-id, "like")]'),
]
for selector in like_selectors:
try:
element = self.wait_for_element(selector, timeout=3)
if element:
element.click()
print("❤️ 点赞成功")
time.sleep(0.5) # 等待动画
return True
except:
continue
print("❌ 未找到点赞按钮")
return False
def comment_on_video(self, comment_text):
"""评论当前视频"""
# 寻找评论按钮
comment_selectors = [
('id', 'com.ss.android.ugc.aweme:id/comment_icon'),
('xpath', '//android.widget.ImageView[@content-desc="评论"]'),
]
for selector in comment_selectors:
try:
element = self.wait_for_element(selector, timeout=3)
if element:
element.click()
time.sleep(2) # 等待评论框出现
# 输入评论
input_selector = ('id', 'com.ss.android.ugc.aweme:id/aew')
input_element = self.wait_for_element(input_selector, timeout=3)
if input_element:
input_element.click()
input_element.send_keys(comment_text)
# 发送评论
send_selector = ('id', 'com.ss.android.ugc.aweme:id/ag4')
send_element = self.wait_for_element(send_selector, timeout=2)
if send_element:
send_element.click()
print(f"💬 评论成功: {comment_text}")
time.sleep(1)
# 返回
self.driver.back()
return True
# 如果没找到输入框,直接返回
self.driver.back()
return False
except:
continue
print("❌ 未找到评论功能")
return False
def follow_current_author(self):
"""关注当前视频作者"""
# 寻找头像或关注按钮
follow_selectors = [
('xpath', '//android.widget.ImageView[@content-desc="头像"]'),
('xpath', '//android.widget.Button[contains(@text, "关注")]'),
]
for selector in follow_selectors:
try:
element = self.wait_for_element(selector, timeout=3)
if element:
element.click()
print("👤 进入作者主页")
time.sleep(2)
# 寻找关注按钮
follow_btn = self.wait_for_element(
('xpath', '//android.widget.Button[contains(@text, "关注")]'),
timeout=3
)
if follow_btn:
follow_btn.click()
print("✅ 关注成功")
time.sleep(1)
# 返回
self.driver.back()
return True
except:
continue
print("❌ 未找到关注功能")
return False
def run_automation_cycle(self, actions_config):
"""运行自动化循环"""
print("🤖 开始抖音自动化任务")
for cycle in range(actions_config.get('cycles', 10)):
print(f"\n🔄 第 {cycle + 1} 个循环:")
# 随机执行动作
if random.random() < actions_config.get('like_probability', 0.7):
self.like_current_video()
if random.random() < actions_config.get('comment_probability', 0.1):
comments = [
"不错👍",
"好看!",
"支持一下",
"厉害了"
]
comment = random.choice(comments)
self.comment_on_video(comment)
if random.random() < actions_config.get('follow_probability', 0.05):
self.follow_current_author()
# 滑动到下一个视频
self.scroll_feed(count=1)
# 随机等待
wait_time = random.uniform(3, 8)
print(f"⏳ 等待 {wait_time:.1f} 秒")
time.sleep(wait_time)
print("🏁 自动化任务完成")
def close(self):
"""关闭驱动"""
if self.driver:
self.driver.quit()
def demo_douyin_automation():
"""演示抖音自动化"""
automation = DouyinAutomation()
actions_config = {
'cycles': 5, # 循环次数
'like_probability': 0.8, # 点赞概率
'comment_probability': 0.1, # 评论概率
'follow_probability': 0.05, # 关注概率
}
try:
automation.run_automation_cycle(actions_config)
except KeyboardInterrupt:
print("\n⏸️ 用户中断")
finally:
automation.close()
if __name__ == "__main__":
demo_douyin_automation()
