1、简介
自动 阅读 趣头条 文本 ,视频,仅此娱乐。
趣头条版本:
Android 模拟器:
对于环境的配置:
Python3 + Appium + 安卓模拟器 实现APP自动化测试,并生成测试报告
自动阅读小视频:
自动阅读文章:
3、代码结构
我们先查看app的 一些信息,比如包名,启动activity 的 名字:
aapt dump badging "apk 本地目录"
aapt dump badging C:\Users\user\Downloads\com.jifen.qukan_30951000.apk
或者 :
adb shell dumpsys activity | grep "mFocusedActivity"
mCurrentFocus=Window{9c8f1dc u0 com.jifen.qukan/com.jifen.qkbase.main.MainActivity}
使用 UiAutoMatorView 抓取 界面 组件 id 等 信息
App.py 用来存放 app 的一些信息
MainRun.py 用来执行的具体函数
Phone.py 用来存放设备的一些信息
4、App.py 文件
class AppInfo:
def __init__(self,app):
self.appPackage = None
self.appActivity = None
if app == "qutoutiao":
self.quToutiao()
# 趣头条 app 信息
def quToutiao(self):
self.appPackage = "com.jifen.qukan"
self.appActivity = "com.jifen.qkbase.main.MainActivity"
class QuTouTiao:
def __init__(self):
# 小视频 流程 组件 id
self.xiaoshiping_id = "com.jifen.qukan:id/amz" # 注意 这个id 是一个 组件 list
self.lingqujinbi_id = "com.jifen.qukan:id/brs" # 右上角 限时领金币
self.toutiaoyemian_id = "com.jifen.qukan:id/kt" # 头条 content 页面的 id
5、phone.py 文件
from appium import webdriver
class PhoneInfo :
def __init__(self,isRealMach):
self.platformName = None
self.platformVersion = None
self.deviceName = None
if isRealMach :
self.setRealDevice()
else:
self.setVirtualDevice()
# 设置虚拟机
def setVirtualDevice(self):
print("虚拟机")
self.platformName = "Android"
self.platformVersion = "6.0.1"
self.deviceName = "127.0.0.1:7555"
# 设置真机信息
def setRealDevice(self):
print("真机")
self.platformName = "Android"
self.platformVersion = "9"
self.deviceName = "Honor"
6、MainRun.py 文件
import random
import re
from time import sleep
from appium import webdriver
from selenium.common.exceptions import WebDriverException, NoSuchElementException
from Phone import PhoneInfo
from App import AppInfo, QuTouTiao
toutiaoWenzhang = 1 #标记头条文章总数
toutiaoShipin = 1 #标记头条视频总数
xiaoshipingNum = 1 #标记小视频总数
class MainRun():
def __init__(self):
print("main run")
phoneInfo = PhoneInfo(False) # 是否是真机
appInfo = AppInfo("qutoutiao")
self.app = QuTouTiao()
self.getDriver(phoneInfo.platformName,phoneInfo.platformVersion,phoneInfo.deviceName,appInfo.appPackage,appInfo.appActivity)
# 手机宽高
self.phoneWidth = self.driver.get_window_size()["width"]
self.phoneHeight = self.driver.get_window_size()["height"]
print("phoneWidth:",self.phoneWidth,"phoneHeight:",self.phoneHeight)
sleep(8) # 延时 8 秒 等待 开机广告
self.xiaoshiping(20,300,15,25) # 每次刷新看 20 个视频,然后刷新,共刷新 300次, 每个视频观看时间随机范围 20,30
#self.touTiao(3,10) #每次刷新下拉3次页面, 每次 刷新 10 次
# 获取 driver 驱动
def getDriver(self,platformName,platformVersion,deviceName,appPackage,appActivity):
desired_caps = {'platformName': platformName , # 平台名称
'platformVersion':platformVersion, # 系统版本号
'deviceName':deviceName, # 设备名称。如果是真机,在'设置->关于手机->设备名称'里查看
'appPackage': appPackage, # apk的包名
'appActivity': appActivity , # activity 名称
'noReset': True, # 账户 密码 不被重置
"newCommandTimeout": 6000 # 在假定客户端退出并结束会话之前,Appium将等待来自客户端的新命令(以秒为单位)
# 'unicodeKeyboard': True, # 使用unicode编码方式发送字符串
# 'resetKeyboard': True # 将键盘隐藏起来,输入中文就要增加这两个参数
}
self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps) # 连接Appium
# 点击小视频 并播放
def xiaoshiping(self,numCount,flashNum,timeOne,timeTwo):
try:
print("小视频 播放")
global xiaoshipingNum
for i in range(flashNum): #遍历每次刷新
sleep(2)
self.driver.find_elements_by_id(self.app.xiaoshiping_id)[2].click()
sleep(2)
for j in range(numCount): #遍历每次下拉
startX = random.randint(0.15*self.phoneWidth,0.75*self.phoneWidth) # 点击的 初始位置 x 坐标 随机
startY = random.randint(0.75*self.phoneHeight,0.95*self.phoneHeight)# 点击的 初始位置 y 坐标
endX = random.randint(0.15*self.phoneWidth,0.75*self.phoneWidth) # 结束时 x 点坐标
endY = random.randint(0.05*self.phoneHeight,0.2*self.phoneHeight)
self.driver.swipe(startX,startY,endX,endY)
try:
guanggao = self.driver.find_element_by_android_uiautomator('new UiSelector().text("广告")') # 过滤广告
if guanggao != None:
print("小视频广告")
except NoSuchElementException :
xiaoshipingNum += 1
print("滑动点为:",startX,startY,endX,endY)
timeGuankan = random.randint(timeOne, timeTwo)
print("观看时间 S: ", timeGuankan)
print("观看的视频个数:",xiaoshipingNum)
sleep(timeGuankan)
if xiaoshipingNum % 30 == 0: # 每观看30 个小视频 就去看一下是否可以领限时金币
self.jinBilingqu(False)
sleep(2)
self.driver.find_elements_by_id(self.app.xiaoshiping_id)[2].click() # 返回小视频界面
sleep(2)
except Exception as error:
print("小视频 error:",error)
MainRun().__init__() # 再次开启本程序
# 头条 阅读
def touTiao(self,xialaCount,flashCount):
try:
print("文章阅读")
global toutiaoWenzhang,toutiaoShipin
for flashNum in range(flashCount): # 刷新一次
self.driver.find_elements_by_id(self.app.xiaoshiping_id)[0].click() # 点击头条页面
sleep(3)
print("刷新次数",flashNum)
for xialaNum in range (xialaCount): # 下拉一次
print("下拉次数",xialaNum)
sleep(3)
elementCount = self.driver.find_element_by_id(self.app.toutiaoyemian_id) # 当前的页面
listElementLayouts = elementCount.find_elements_by_class_name("android.widget.LinearLayout") # 当前头条页面包含的 list
for elementLay in listElementLayouts: # 遍历当前 页面 lay
isVideo = False
isGuaggao = False
print("lay index:",listElementLayouts.index(elementLay),len(listElementLayouts))
textViewList = elementLay.find_elements_by_class_name("android.widget.TextView") # 寻找当前框 包含内容
for textView in textViewList:
text = textView.text
if text == "置顶" or text == "广告" or "小视频" in text: #过滤是否是广告
print("是置顶文章 或 广告")
isGuaggao = True
break
ret = re.match(r'(\d{2}):(\d{2})', text) # 匹配 是不是 视频 03:56 格式
if ret != None:
print("是视频",text,"观看量",toutiaoShipin)
toutiaoShipin += 1
isVideo = True
elementLay.click()
watchTime = int(text.split(":")[0])
sleep(watchTime*60 + int(text.split(":")[1]) + 5) # 等待视频观看时间
self.driver.back() # 返回头条主页面
sleep(1)
if toutiaoShipin % 3 == 0: #每看三个视频 领取金币
self.jinBilingqu(True)
if not isVideo and not isGuaggao:
print("是文章",text,"阅读量",toutiaoWenzhang)
toutiaoWenzhang += 1
elementLay.click()
print("开始阅读文章")
sleep(2)
i = 0
swipNum = random.randint(30,50)
while True:
startX = random.uniform(0.40 * self.phoneWidth, 0.60 * self.phoneWidth) # 点击的 初始位置 x 坐标 随机
startY = random.uniform(0.75 * self.phoneHeight, 0.85 * self.phoneHeight)
endX = random.uniform(0.40 * self.phoneWidth, 0.60 * self.phoneWidth) # 结束时 x 点坐标
endY = random.uniform(0.6 * self.phoneHeight, 0.7 * self.phoneHeight) # 点击的 初始位置 y 坐标
if startY - endY > 0.1*self.phoneHeight :
i += 1
duringTime = random.uniform(1,3) #滑动时间
self.driver.swipe(startX,startY,endX,endY)
print("滑动距离 %.2f" % (startY - endY),"滑动时间 %.2f" % duringTime)
sleep(duringTime)
print("正在阅读文章",i,"/",swipNum)
if i > swipNum: # 一篇文章上划多少次之后退出
break
print("结束一篇文章阅读")
self.driver.back()
sleep(1)
if toutiaoWenzhang % 6 == 0: #每看路篇文章就看限时金币是否可以领取
self.jinBilingqu(True)
startX = random.randint(0.40 * self.phoneWidth, 0.60 * self.phoneWidth) # 下拉整个页面
endX = random.randint(0.40 * self.phoneWidth, 0.60 * self.phoneWidth)
self.driver.swipe(startX,0.9*self.phoneHeight,endX,0.4*self.phoneHeight) #整个 页面上划
self.driver.swipe(startX,0.9*self.phoneHeight,endX,0.4*self.phoneHeight) #整个 页面上划
except WebDriverException as error:
print("头条阅读 error :",error)
MainRun().__init__() # 再次开启本程序
# 右上角 金币领取
def jinBilingqu(self,isToutiaoJiMian):
try:
print("右上角金币限时领取")
if not isToutiaoJiMian:
self.driver.find_elements_by_id(self.app.xiaoshiping_id)[0].click() # 点击下面状态栏 头条 按钮
else:
self.driver.implicitly_wait(3)
element = self.driver.find_element_by_id(self.app.lingqujinbi_id)
if element != None and element.text == "领取":
element.click()
print("领取限时金币")
else:
print("还不能领取限时金币")
except Exception as error:
print("金币领取 error: ",error)
if __name__ == "__main__":
MainRun()
至此已经支持 自动阅读 观看视频 和 观看小视频 以及自动领取限时金币 功能。
还有想刷金币的同学,不要用模拟器,也不要把账号在不同设备上来回登录 不然 like this: