【抖音养号】adb

-- coding: utf-8 --

㊎ Author : XMZ

㊍ Time : 2023/11/26 13:30

㊌ File : android-adb->dy_automation.py

㊋ IDE : PyCharm

㊏ REMARKS:

import re
import os
import time

import cv2
import sys
import jieba
import base64
import random
import logging
import subprocess
import pytesseract
from PIL import Image

self_path = os.path.dirname(os.path.abspath(__file__))
father_path = os.path.dirname(self_path)
parent_path = os.path.dirname(father_path)
sys.path.append(self_path)
sys.path.append(father_path)
sys.path.append(parent_path)
from SystemEnvConfiguration.loger import LogGer
from SystemEnvConfiguration.plugins import requester

class DouyinAuto(object):
    """
    #启动命令
    adb shell am start -n com.ss.android.ugc.aweme/.main.MainActivity
    """
    LogGer(str(os.path.basename(__file__))[:-3])

    def __init__(self):
        try:
            adb_output = subprocess.check_output("adb devices", shell=True, text=True)
            info = adb_output.split("attached\n")[1].strip().split("\t")[0]
            logging.info(f"已连接设备:{info}")
        except subprocess.CalledProcessError:
            logging.info("没有连接的设备")
            sys.exit()
        self.package_name = "com.ss.android.ugc.aweme"
        self.access_token = "xxxxxx"

    def get_version(self) -> str:
        """
        获取软件信息
        :return:26.4.0
        """
        adb_command = f"adb shell dumpsys package {self.package_name}"
        try:
            adb_output = subprocess.check_output(adb_command, shell=True, text=True)
            version_info = None
            for line in adb_output.splitlines():
                if "versionName=" in line:
                    version_info = line.split("=")[1]
                    break
            return version_info
        except subprocess.CalledProcessError:
            return "0.0.0"

    @staticmethod
    def get_hardware_info():
        """
        获取机器的硬件信息
        :return: Hisilicon Kirin985
        """
        adb_command = "adb shell cat /proc/cpuinfo"
        try:
            adb_output = subprocess.check_output(adb_command, shell=True, text=True)
            hardware_info = adb_output.split("\nHardware", 1)[1].strip().replace(': ', '')
            return hardware_info
        except subprocess.CalledProcessError:
            return '0'

    @staticmethod
    def get_mm_size():
        command = "adb shell wm size"
        try:
            mm_size = subprocess.check_output(command, shell=True, text=True).strip()
            size = mm_size.split(":", 1)[1].split('x')
            keys = ['x', 'y']
            numeric_values = [int(value.strip()) for value in size]
            result_dict = dict(zip(keys, numeric_values))
            return result_dict
        except subprocess.CalledProcessError:
            return {'x': 1200, 'y': 2000}

    @staticmethod
    def get_android_version():
        """
        获取android版本信息
        :return:
        """
        adb_command = "adb shell getprop ro.build.version.release"
        try:
            android_version = subprocess.check_output(adb_command, shell=True, text=True).strip()
            return android_version
        except subprocess.CalledProcessError:
            return '0'

    def print_info(self):
        logging.info(f"获取APP版本号:{self.get_version()}")
        logging.info(f"获取硬件信息:{self.get_hardware_info()}")
        logging.info(f"获取android版本:Android {self.get_android_version()}")

    def start_app(self):
        """
        启动APP
        :return:
        """
        command = "adb shell am start -n com.ss.android.ugc.aweme/.main.MainActivity"
        try:
            output = subprocess.check_output(command, shell=True, text=True)
            time.sleep(5)
            return output.strip()
        except subprocess.CalledProcessError as e:
            logging.error(f"启动APP执行命令时出错: {command}")
            logging.error(e.output)
            return None

    def slide(self, frequency=1, sleep_time=1):
        """
        滑动
        :return:
        """
        for i in range(frequency):
            start_x, start_y = random.randint(750, 950), random.randint(1480, 1615)
            end_x, end_y = random.randint(900, 1000), random.randint(1000, 1100)
            # 滑动时间(毫秒)
            duration = random.randint(100, 200)
            adb_command = f'adb shell input swipe {start_x} {start_y} {end_x} {end_y} {duration}'
            try:
                subprocess.run(adb_command, shell=True, check=True)
                print(f"Screen swiped from ({start_x}, {start_y}) to ({end_x}, {end_y}) in {duration} milliseconds.")
            except subprocess.CalledProcessError as e:
                print(f"Error executing command: {adb_command}")
                print(e.output)
            time.sleep(sleep_time)

    def capture_screen(self, retry=3):
        """
        截图
        :return:
        """
        try:
            filename = "Pictures/Screenshots/adb_screenshot.png"
            # 使用adb截屏命令获取屏幕截图,保存到设备上
            adb_command = f'adb shell screencap -p /sdcard/{filename}'
            subprocess.run(adb_command, shell=True, check=True)
        except subprocess.CalledProcessError:
            return None if retry == 0 else self.capture_screen(retry - 1)

    def pull_screenshot(self, retry=3):
        """
        使用adb pull命令将设备上的截图拉取到计算机上
        :return:
        """
        try:
            filename = "Pictures/Screenshots/adb_screenshot.png"
            adb_command = f'adb pull /sdcard/{filename} {self_path}'
            subprocess.run(adb_command, shell=True, check=True)
        except subprocess.CalledProcessError:
            return None if retry == 0 else self.pull_screenshot(retry - 1)

    def ocr_screen(self):
        """
        裁剪图片
        左上角坐标(left, top):(0, 1000)
        右下角坐标(right, bottom):(1200, 2000)
        :return:
        """
        left, top = 10, 1500  # 左上角坐标
        right, bottom = 1097, 1900  # 右下角坐标
        image = Image.open('adb_screenshot.png')
        img_cropped = image.crop((left, top, right, bottom))
        # # 保存图片
        img_cropped.save('screenshot_cropped.png')

    def general_basic(self):
        """
        百度OCR :general_basic,5W
        :return:
        """
        _url = f"https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token={self.access_token}"
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        f = open('screenshot_cropped.png', 'rb')
        img = base64.b64encode(f.read())
        params = {"image": img}
        response = requester(url=_url, method="post", headers=headers, data=params).json()
        words_result = response.get("words_result")
        words = [key.get("words") for key in words_result]
        # 提取汉子:
        chinese_characters = re.findall(r'[\u4e00-\u9fff]+', "".join(words))
        # 使用jieba进行分词
        words_ = ','.join(jieba.cut_for_search(''.join(chinese_characters))).split(',')
        return words_

    def determine_keywords(self):
        """
        判断关键字,是否评论
        :return:
        """
        # 截图
        self.capture_screen()
        # 上传截图
        self.pull_screenshot()
        # 裁剪图片
        self.ocr_screen()
        # 百度接口识别文字
        words = self.general_basic()
        keyword = "旗袍/爱看/擦边/穿衣自由/黑丝/甜妹/短裙/黄色/后妈/模特/实名/观看/丰满/碎花/男友/视角/反差/小妈/变装/性感/大长/长腿/腿/御姐/极品/身材/马甲/辣妹/美女/纯欲/艾特/jk/制服/不良/战袍/腰臀/热舞/少女/顶得住/制服".split(
            '/')
        common_elements = [word for word in words if word in keyword]
        logging.info(f"百度识别关键词:{words}")
        logging.info(f"自定义关键词:{keyword}")
        logging.info(f"匹配到关键词:{common_elements}")
        return common_elements if common_elements else False

    def click_on(self):
        """
        点击评论按钮
        :return:
        """
        logging.info("触发评论")
        # 切换输入法
        os.system('adb shell ime set com.android.adbkeyboard/.AdbIME')
        # 设置点击的屏幕坐标
        x, y = 1139, 1425
        # 使用ADB模拟点击事件
        os.system(f'adb shell input tap {x} {y}')
        logging.info('点击评论按钮完成!')
        time.sleep(0.5)
        # 滑动屏幕
        self.slide(random.randint(1, 3), random.randint(1, 3))
        # 点击输入框
        start_x, start_y = random.randint(100, 300), random.randint(1929, 1964)
        os.system(f'adb shell input tap {start_x} {start_y}')
        logging.info('点击输入框完成!')
        time.sleep(1)
        # 使用ADB在输入框中输入文字
        # 二次点击输入框
        start_x, start_y = random.randint(150, 300), random.randint(1810, 1875)
        os.system(f'adb shell input tap {start_x} {start_y}')
        logging.info('二次点击输入框完成!')
        time.sleep(1)
        # 输入文本
        expression = ['[比心]', '[送心]', '[赞]', '[爱心]', '[玫瑰]', '[看]', '[干饭人]']
        text = random.choice(expression) * random.randint(1, 4)
        os.system(f"adb shell am broadcast -a ADB_INPUT_TEXT --es msg '{text}'")
        logging.info(f'内容输入完成:{text}')
        time.sleep(1)
        # 点击发送
        start_x, start_y = random.randint(1085, 1155), random.randint(1837, 1888)
        os.system(f'adb shell input tap {start_x} {start_y}')
        logging.info('点击发送完成!')
        # 点击空白退出
        time.sleep(0.5)
        os.system(f'adb shell input tap {random.randint(300, 700)} {random.randint(280, 460)}')

    def main_logic(self):
        """
        串联完整进程
        :return:
        """
        # 启动APP
        self.start_app()
        # 输出版本信息
        self.print_info()
        random_number = random.randint(30, 100)
        for _ in range(random_number):
            # 关键词判断,Ture停留15秒,False划走
            result = self.determine_keywords()
            logging.info(f"未匹配关键词:{result}") if result is False else None
            if result:
                time.sleep(random.randint(6, 12))
                self.click_on() if random.randint(1, 10) == 8 else logging.info("未触发评论")
            self.slide()
            logging.info(f"总次数:{random_number},已完成次数:{_}")

    def __del__(self):
        # 切换输入法
        time.sleep(1)
        os.system('adb shell ime set com.baidu.input_hihonor/com.baidu.input_huawei.ImeService')
        time.sleep(1)
        # # 使用ADB关闭应用
        os.system(f'adb shell am force-stop {self.package_name}')


if __name__ == '__main__':
    dy = DouyinAuto()
    # dy.capture_screen()
    # dy.pull_screenshot()
    # dy.click_on()
    dy.main_logic()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值