Repository: wangshub/Douyin-Bot Branch: master Commit: 399c19b662ac Files: 25 Total size: 24.4 KB Directory structure: gitextract_w5uw559i/ ├── .gitignore ├── LICENSE ├── README.md ├── Tools/ │ └── README.md ├── apk/ │ ├── ADBKeyBoard.apk │ └── aapt ├── common/ │ ├── UnicodeStreamFilter.py │ ├── __init__.py │ ├── apiutil.py │ ├── auto_adb.py │ ├── compression.py │ ├── config.py │ ├── debug.py │ ├── excel_keyword.py │ └── screenshot.py ├── config/ │ ├── 1280x720/ │ │ └── config.json │ ├── 1920x1080/ │ │ └── config.json │ └── default.json ├── douyin-bot.py ├── example/ │ ├── test_crop.py │ ├── test_plot.py │ ├── test_readExcel.py │ └── test_textInput.py ├── reply/ │ └── data.json └── requirements.txt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .idea/ .DS_Store # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ face/ autojump.png optimized.png ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 神奇的战士-王松 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # 如何在抖音上找到漂亮小姐姐----抖音机器人 [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badge/) [![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php) 最近沉迷于抖音无法自拔,常常花好几个小时在抖音**漂亮小姐姐**身上。 本着**高效、直接**地找到漂亮小姐姐的核心思想,我用 Python + ADB 做了一个 Python 抖音机器人 Douyin-Bot。 ## 特性 - [x] **自动翻页** - [x] **颜值检测** - [x] **人脸识别** - [x] **自动点赞** - [x] **自动关注** - [x] 随机防 Ban - [x] **自动评论** ## 原理 - 打开《抖音短视频》APP,进入主界面 - 获取手机截图,并对截图进行压缩 (Size < 1MB); - 请求 [人脸识别 API](http://ai.qq.com/); - 解析返回的人脸 Json 信息,对人脸检测切割; - 当颜值大于门限值 `BEAUTY_THRESHOLD`时,点赞并关注; - 下一页,返回第一步; ## 使用教程 - Python版本:3.0及以上 - 相关软件工具安装和使用步骤请参考 [wechat_jump_game](https://github.com/wangshub/wechat_jump_game) 和 [Android 操作步骤](https://github.com/wangshub/wechat_jump_game/wiki/Android-%E5%92%8C-iOS-%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4) - 在 [ai.qq.com](https://ai.qq.com) 免费申请 `AppKey` 和 `AppID` 1. 获取源码:`git clone https://github.com/wangshub/Douyin-Bot.git` 2. 进入源码目录: `cd Douyin-Bot` 3. 安装依赖: `pip install -r requirements.txt` 4. 运行程序:`python douyin-bot.py` 5. [自动评论](https://zhuanlan.zhihu.com/p/57242891)(可选):`python3 douyin-bot.py --reply` ## 注意 - 目前暂时只适配了 一加5(1920x1080 分辨率),如果手机不是该分辨率,请修改 `config/` 文件夹下面的配置文件; - `config.json`配置文件参考: - `center_point`: 屏幕中心点`(x, y)`,区域范围 `rx, ry` - `follow_bottom`: 关注按钮位置`(x, y)`,区域范围 `rx, ry` - `star_bottom`: 点赞按钮位置`(x, y)`,区域范围 `rx, ry` ## 脸部截取 ![](./screenshot/faces.png) ## LICENSE MIT 欢迎 Star 和 Fork ~ 如果你有什么问题请提 Issue,或者关注我的微信公众号留言,我都会一一解答

================================================ FILE: Tools/README.md ================================================ ## 所有实验都在该文件夹下运行即可,已放上测试用的代码。免去配置 adb 的麻烦 - 复制 wechat_jump_game 根目录下的 config 文件夹以及 wechat_jump_py3.py 文件到本目录下 - 按住 `shift` + 右键 选择在该文件夹下打开命令窗口(Windows 用户请自行 cmd) - 打开安卓手机的 usb 调试,并连接电脑,在终端输入 `adb devices` 进行测试,如果有连接设备号则表示成功 - 打开微信小游戏,然后运行代码 `python wechat_jump_py3.py`,点击出现的图形起点和终点,棋子自动跳转 **注意:这里使用的是不需要配置的 adb 方式,需要在该文件下操作,至于如何自动跳转,只需改变执行脚本即可,这里只做演示** ================================================ FILE: common/UnicodeStreamFilter.py ================================================ # -*- coding: utf-8 -*- import sys if sys.version_info.major != 3: class UnicodeStreamFilter: def __init__(self, target): self.target = target self.encoding = 'utf-8' self.errors = 'replace' self.encode_to = self.target.encoding def write(self, s): if type(s) == str: s = s.decode("utf-8") s = s.encode(self.encode_to, self.errors).decode(self.encode_to) self.target.write(s) if sys.stdout.encoding == 'cp936': sys.stdout = UnicodeStreamFilter(sys.stdout) else: pass ================================================ FILE: common/__init__.py ================================================ ================================================ FILE: common/apiutil.py ================================================ #-*- coding: UTF-8 -*- import hashlib import urllib from urllib import parse import urllib.request import base64 import json import time url_preffix='https://api.ai.qq.com/fcgi-bin/' def setParams(array, key, value): array[key] = value def genSignString(parser): uri_str = '' for key in sorted(parser.keys()): if key == 'app_key': continue uri_str += "%s=%s&" % (key, parse.quote(str(parser[key]), safe='')) sign_str = uri_str + 'app_key=' + parser['app_key'] hash_md5 = hashlib.md5(sign_str.encode('utf-8')) return hash_md5.hexdigest().upper() class AiPlat(object): def __init__(self, app_id, app_key): self.app_id = app_id self.app_key = app_key self.data = {} self.url_data = '' def invoke(self, params): self.url_data = urllib.parse.urlencode(params).encode("utf-8") req = urllib.request.Request(self.url, self.url_data) try: rsp = urllib.request.urlopen(req) str_rsp = rsp.read().decode('utf-8') dict_rsp = json.loads(str_rsp) return dict_rsp except Exception as e: print(e) return {'ret': -1} def face_detectface(self, image, mode): self.url = url_preffix + 'face/face_detectface' setParams(self.data, 'app_id', self.app_id) setParams(self.data, 'app_key', self.app_key) setParams(self.data, 'mode', mode) setParams(self.data, 'time_stamp', int(time.time())) setParams(self.data, 'nonce_str', int(time.time())) image_data = base64.b64encode(image) setParams(self.data, 'image', image_data.decode("utf-8")) sign_str = genSignString(self.data) setParams(self.data, 'sign', sign_str) return self.invoke(self.data) ================================================ FILE: common/auto_adb.py ================================================ # -*- coding: utf-8 -*- import os import subprocess import platform class auto_adb(): def __init__(self): try: adb_path = 'adb' subprocess.Popen([adb_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.adb_path = adb_path except OSError: if platform.system() == 'Windows': adb_path = os.path.join('Tools', "adb", 'adb.exe') try: subprocess.Popen( [adb_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.adb_path = adb_path except OSError: pass else: try: subprocess.Popen( [adb_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: pass print('请安装 ADB 及驱动并配置环境变量') exit(1) def get_screen(self): process = os.popen(self.adb_path + ' shell wm size') output = process.read() return output def run(self, raw_command): print(raw_command) command = '{} {}'.format(self.adb_path, raw_command) process = os.popen(command) output = process.read() return output def test_device(self): print('检查设备是否连接...') command_list = [self.adb_path, 'devices'] process = subprocess.Popen(command_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = process.communicate() if output[0].decode('utf8') == 'List of devices attached\n\n': print('未找到设备') print('adb 输出:') for each in output: print(each.decode('utf8')) exit(1) print('设备已连接') print('adb 输出:') for each in output: print(each.decode('utf8')) def test_density(self): process = os.popen(self.adb_path + ' shell wm density') output = process.read() return output def test_device_detail(self): process = os.popen(self.adb_path + ' shell getprop ro.product.device') output = process.read() return output def test_device_os(self): process = os.popen(self.adb_path + ' shell getprop ro.build.version.release') output = process.read() return output def adb_path(self): return self.adb_path ================================================ FILE: common/compression.py ================================================ from PIL import Image import math import os def resize_image(origin_img, optimize_img, threshold): """ shrink image by size :param origin_img: :param optimize_img: :param threshold: :return: """ file_size = os.path.getsize(origin_img) with Image.open(origin_img) as im: if file_size > threshold: width, height = im.size if width >= height: new_width = int(math.sqrt(threshold / 2)) new_height = int(new_width * height * 1.0 / width) else: new_height = int(math.sqrt(threshold / 2)) new_width = int(new_height * width * 1.0 / height) resized_im = im.resize((new_width, new_height)) resized_im.save(optimize_img) else: im.save(optimize_img) ================================================ FILE: common/config.py ================================================ # -*- coding: utf-8 -*- """ 调取配置文件和屏幕分辨率的代码 """ import os import sys import json import re from common.auto_adb import auto_adb adb = auto_adb() def open_accordant_config(): """ 调用配置文件 """ screen_size = _get_screen_size() config_file = "{path}/config/{screen_size}/config.json".format( path=sys.path[0], screen_size=screen_size ) # 优先获取执行文件目录的配置文件 here = sys.path[0] for file in os.listdir(here): if re.match(r'(.+)\.json', file): file_name = os.path.join(here, file) with open(file_name, 'r') as f: print("Load config file from {}".format(file_name)) return json.load(f) # 根据分辨率查找配置文件 if os.path.exists(config_file): with open(config_file, 'r') as f: print("正在从 {} 加载配置文件".format(config_file)) return json.load(f) else: with open('{}/config/default.json'.format(sys.path[0]), 'r') as f: print("Load default config") return json.load(f) def _get_screen_size(): """ 获取手机屏幕大小 """ size_str = adb.get_screen() m = re.search(r'(\d+)x(\d+)', size_str) if m: return "{height}x{width}".format(height=m.group(2), width=m.group(1)) return "1920x1080" ================================================ FILE: common/debug.py ================================================ # -*- coding: utf-8 -*- """ 这是debug的代码,当DEBUG_SWITCH开关开启的时候,会将各种信息存在本地,方便检查故障 """ import os import sys import shutil import math from PIL import ImageDraw import platform if platform.system() == 'Windows': os.chdir(os.getcwd().replace('\\common', '')) path_split = "\\" else: os.chdir(os.getcwd().replace('/common', '')) path_split = '/' # from common import ai try: from common.auto_adb import auto_adb except ImportError as ex: print(ex) print('请将脚本放在项目根目录中运行') print('请检查项目根目录中的 common 文件夹是否存在') exit(1) screenshot_backup_dir = 'screenshot_backups' adb = auto_adb() def make_debug_dir(screenshot_backup_dir): """ 创建备份文件夹 """ if not os.path.isdir(screenshot_backup_dir): os.mkdir(screenshot_backup_dir) def backup_screenshot(ts): """ 为了方便失败的时候 debug """ make_debug_dir(screenshot_backup_dir) shutil.copy('{}{}autojump.png'.format(os.getcwd(), path_split), os.path.join(os.getcwd(), screenshot_backup_dir, str(ts) + '.png')) def save_debug_screenshot(ts, im, piece_x, piece_y, board_x, board_y): """ 对 debug 图片加上详细的注释 """ make_debug_dir(screenshot_backup_dir) draw = ImageDraw.Draw(im) draw.line((piece_x, piece_y) + (board_x, board_y), fill=2, width=3) draw.line((piece_x, 0, piece_x, im.size[1]), fill=(255, 0, 0)) draw.line((0, piece_y, im.size[0], piece_y), fill=(255, 0, 0)) draw.line((board_x, 0, board_x, im.size[1]), fill=(0, 0, 255)) draw.line((0, board_y, im.size[0], board_y), fill=(0, 0, 255)) draw.ellipse((piece_x - 10, piece_y - 10, piece_x + 10, piece_y + 10), fill=(255, 0, 0)) draw.ellipse((board_x - 10, board_y - 10, board_x + 10, board_y + 10), fill=(0, 0, 255)) del draw im.save(os.path.join(os.getcwd(), screenshot_backup_dir, '#' + str(ts) + '.png')) def computing_error(last_press_time, target_board_x, target_board_y, last_piece_x, last_piece_y, temp_piece_x, temp_piece_y): """ 计算跳跃实际误差 """ target_distance = math.sqrt( (target_board_x - last_piece_x) ** 2 + (target_board_y - last_piece_y) ** 2) # 上一轮目标跳跃距离 actual_distance = math.sqrt((temp_piece_x - last_piece_x) ** 2 + (temp_piece_y - last_piece_y) ** 2) # 上一轮实际跳跃距离 jump_error_value = math.sqrt((target_board_x - temp_piece_x) ** 2 + (target_board_y - temp_piece_y) ** 2) # 跳跃误差 print(round(target_distance), round(jump_error_value), round(actual_distance), round(last_press_time)) ''''# 将结果采集进学习字典 if last_piece_x > 0 and last_press_time > 0: ai.add_data(round(actual_distance, 2), round(last_press_time)) # print(round(actual_distance), round(last_press_time))''' def dump_device_info(): """ 显示设备信息 """ size_str = adb.get_screen() device_str = adb.test_device_detail() phone_os_str = adb.test_device_os() density_str = adb.test_density() print("""********** Screen: {size} Density: {dpi} Device: {device} Phone OS: {phone_os} Host OS: {host_os} Python: {python} **********""".format( size=size_str.replace('\n', ''), dpi=density_str.replace('\n', ''), device=device_str.replace('\n', ''), phone_os=phone_os_str.replace('\n', ''), host_os=sys.platform, python=sys.version )) ================================================ FILE: common/excel_keyword.py ================================================ import xlrd import random def get_random_keyword(filename): """ get random row of filename :param filename: :return: """ try: with xlrd.open_workbook(filename) as data: table = data.sheets()[0] data_list = [] data_list.extend(table.col_values(0)) return data_list[random.randint(0, len(data_list))] except Exception as error: print(Exception) return 'BRAVO' if __name__ == '__main__': reply = get_random_keyword('../reply/keyword.xlsx') print(reply) ================================================ FILE: common/screenshot.py ================================================ # -*- coding: utf-8 -*- """ 手机屏幕截图的代码 """ import subprocess import os import sys from PIL import Image from io import StringIO try: from common.auto_adb import auto_adb except Exception as ex: print(ex) print('请将脚本放在项目根目录中运行') print('请检查项目根目录中的 common 文件夹是否存在') exit(1) adb = auto_adb() # SCREENSHOT_WAY 是截图方法,经过 check_screenshot 后,会自动递减,不需手动修改 SCREENSHOT_WAY = 3 def pull_screenshot(): """ 获取屏幕截图,目前有 0 1 2 3 四种方法,未来添加新的平台监测方法时, 可根据效率及适用性由高到低排序 """ global SCREENSHOT_WAY if 1 <= SCREENSHOT_WAY <= 3: process = subprocess.Popen( adb.adb_path + ' shell screencap -p', shell=True, stdout=subprocess.PIPE) binary_screenshot = process.stdout.read() if SCREENSHOT_WAY == 2: binary_screenshot = binary_screenshot.replace(b'\r\n', b'\n') elif SCREENSHOT_WAY == 1: binary_screenshot = binary_screenshot.replace(b'\r\r\n', b'\n') return Image.open(StringIO(binary_screenshot)) elif SCREENSHOT_WAY == 0: adb.run('shell screencap -p /sdcard/autojump.png') adb.run('pull /sdcard/autojump.png .') return Image.open('./autojump.png') def check_screenshot(): """ 检查获取截图的方式 """ global SCREENSHOT_WAY if os.path.isfile('autojump.png'): try: os.remove('autojump.png') except Exception: pass if SCREENSHOT_WAY < 0: print('暂不支持当前设备') sys.exit() try: im = pull_screenshot() im.load() im.close() print('采用方式 {} 获取截图'.format(SCREENSHOT_WAY)) except Exception: SCREENSHOT_WAY -= 1 check_screenshot() ================================================ FILE: config/1280x720/config.json ================================================ { "center_point":{ "x": 333, "y": 700, "rx": 10, "ry": 300 }, "follow_bottom":{ "x": 648, "y": 534, "rx": 10, "ry": 10 }, "star_bottom":{ "x": 641, "y": 642, "rx": 10, "ry": 10 } } ================================================ FILE: config/1920x1080/config.json ================================================ { "center_point":{ "x": 540, "y": 965, "rx": 10, "ry": 300 }, "follow_bottom":{ "x": 983, "y": 854, "rx": 10, "ry": 10 }, "star_bottom":{ "x": 986, "y": 994, "rx": 10, "ry": 10 }, "comment_bottom":{ "x": 1000, "y": 1240, "rx": 10, "ry": 10 }, "comment_text":{ "x": 300, "y": 1855, "rx": 10, "ry": 10 }, "comment_send":{ "x": 1010, "y": 1690, "rx": 10, "ry": 10 } } ================================================ FILE: config/default.json ================================================ { "center_point":{ "x": 540, "y": 965, "rx": 10, "ry": 300 }, "follow_bottom":{ "x": 990, "y": 950, "rx": 10, "ry": 10 }, "star_bottom":{ "x": 1000, "y": 1083, "rx": 10, "ry": 10 }, "comment_bottom":{ "x": 1000, "y": 1240, "rx": 10, "ry": 10 }, "comment_text":{ "x": 300, "y": 1855, "rx": 10, "ry": 10 }, "comment_send":{ "x": 1010, "y": 1690, "rx": 10, "ry": 10 } } ================================================ FILE: douyin-bot.py ================================================ # -*- coding: utf-8 -*- import sys import random import time from PIL import Image import argparse if sys.version_info.major != 3: print('Please run under Python3') exit(1) try: from common import debug, config, screenshot, UnicodeStreamFilter from common.auto_adb import auto_adb from common import apiutil from common.compression import resize_image except Exception as ex: print(ex) print('请将脚本放在项目根目录中运行') print('请检查项目根目录中的 common 文件夹是否存在') exit(1) VERSION = "0.0.1" # 我申请的 Key,随便用,嘻嘻嘻 # 申请地址 http://ai.qq.com AppID = '1106858595' AppKey = 'bNUNgOpY6AeeJjFu' DEBUG_SWITCH = True FACE_PATH = 'face/' adb = auto_adb() adb.test_device() config = config.open_accordant_config() # 审美标准 BEAUTY_THRESHOLD = 80 # 最小年龄 GIRL_MIN_AGE = 14 def yes_or_no(): """ 检查是否已经为启动程序做好了准备 """ while True: yes_or_no = str(input('请确保手机打开了 ADB 并连接了电脑,' '然后打开手机软件,确定开始?[y/n]:')) if yes_or_no == 'y': break elif yes_or_no == 'n': print('谢谢使用') exit(0) else: print('请重新输入') def _random_bias(num): """ random bias :param num: :return: """ return random.randint(-num, num) def next_page(): """ 翻到下一页 :return: """ cmd = 'shell input swipe {x1} {y1} {x2} {y2} {duration}'.format( x1=config['center_point']['x'], y1=config['center_point']['y']+config['center_point']['ry'], x2=config['center_point']['x'], y2=config['center_point']['y'], duration=200 ) adb.run(cmd) time.sleep(1.5) def follow_user(): """ 关注用户 :return: """ cmd = 'shell input tap {x} {y}'.format( x=config['follow_bottom']['x'] + _random_bias(10), y=config['follow_bottom']['y'] + _random_bias(10) ) adb.run(cmd) time.sleep(0.5) def thumbs_up(): """ 点赞 :return: """ cmd = 'shell input tap {x} {y}'.format( x=config['star_bottom']['x'] + _random_bias(10), y=config['star_bottom']['y'] + _random_bias(10) ) adb.run(cmd) time.sleep(0.5) def tap(x, y): cmd = 'shell input tap {x} {y}'.format( x=x + _random_bias(10), y=y + _random_bias(10) ) adb.run(cmd) def auto_reply(): msg = "垆边人似月,皓腕凝霜雪。就在刚刚,我的心动了一下,小姐姐你好可爱呀_Powered_By_Python" # 点击右侧评论按钮 tap(config['comment_bottom']['x'], config['comment_bottom']['y']) time.sleep(1) #弹出评论列表后点击输入评论框 tap(config['comment_text']['x'], config['comment_text']['y']) time.sleep(1) #输入上面msg内容 ,注意要使用ADB keyboard 否则不能自动输入,参考: https://www.jianshu.com/p/2267adf15595 cmd = 'shell am broadcast -a ADB_INPUT_TEXT --es msg {text}'.format(text=msg) adb.run(cmd) time.sleep(1) # 点击发送按钮 tap(config['comment_send']['x'], config['comment_send']['y']) time.sleep(0.5) # 触发返回按钮, keyevent 4 对应安卓系统的返回键,参考KEY 对应按钮操作: https://www.cnblogs.com/chengchengla1990/p/4515108.html cmd = 'shell input keyevent 4' adb.run(cmd) def parser(): ap = argparse.ArgumentParser() ap.add_argument("-r", "--reply", action='store_true', help="auto reply") args = vars(ap.parse_args()) return args def main(): """ main :return: """ print('程序版本号:{}'.format(VERSION)) print('激活窗口并按 CONTROL + C 组合键退出') debug.dump_device_info() screenshot.check_screenshot() cmd_args = parser() while True: next_page() time.sleep(1) screenshot.pull_screenshot() resize_image('autojump.png', 'optimized.png', 1024*1024) with open('optimized.png', 'rb') as bin_data: image_data = bin_data.read() ai_obj = apiutil.AiPlat(AppID, AppKey) rsp = ai_obj.face_detectface(image_data, 0) major_total = 0 minor_total = 0 if rsp['ret'] == 0: beauty = 0 for face in rsp['data']['face_list']: msg_log = '[INFO] gender: {gender} age: {age} expression: {expression} beauty: {beauty}'.format( gender=face['gender'], age=face['age'], expression=face['expression'], beauty=face['beauty'], ) print(msg_log) face_area = (face['x'], face['y'], face['x']+face['width'], face['y']+face['height']) img = Image.open("optimized.png") cropped_img = img.crop(face_area).convert('RGB') cropped_img.save(FACE_PATH + face['face_id'] + '.png') # 性别判断 if face['beauty'] > beauty and face['gender'] < 50: beauty = face['beauty'] if face['age'] > GIRL_MIN_AGE: major_total += 1 else: minor_total += 1 # 是个美人儿~关注点赞走一波 if beauty > BEAUTY_THRESHOLD and major_total > minor_total: print('发现漂亮妹子!!!') thumbs_up() follow_user() if cmd_args['reply']: auto_reply() else: print(rsp) continue if __name__ == '__main__': try: # yes_or_no() main() except KeyboardInterrupt: adb.run('kill-server') print('谢谢使用') exit(0) ================================================ FILE: example/test_crop.py ================================================ from PIL import Image im = Image.open("../autojump.png") w, h = im.size area = (0, 0, 50, 50) im_croped = im.crop(area) im_croped.show() ================================================ FILE: example/test_plot.py ================================================ import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as np # img = mpimg.imread('../screenshot/main_page.jpeg') # img = mpimg.imread('../screenshot/main_page.jpeg') # img = mpimg.imread('../screenshot/news_normal.jpeg') # img = mpimg.imread('../screenshot/news_comment.jpeg') # img = mpimg.imread('../screenshot/comment_comment.jpeg') # img = mpimg.imread('../screenshot/add_comment.jpeg') img = mpimg.imread('../autojump.png') imgplot = plt.imshow(img) plt.show() ================================================ FILE: example/test_readExcel.py ================================================ import xlrd import random #打开excel文件 data=xlrd.open_workbook('../reply/keyword.xlsx') #获取第一张工作表(通过索引的方式) table=data.sheets()[0] #data_list用来存放数据 data_list=[] #将table中第一行的数据读取并添加到data_list中 data_list.extend(table.col_values(0)) #打印出第一行的全部数据 for item in data_list: print(item) ================================================ FILE: example/test_textInput.py ================================================ import os def adb_keyboard_input(text): """ adb keyboard app input unicode text :param text: :return: """ cmd = 'adb shell am broadcast -a ADB_INPUT_TEXT --es msg {text}'.format(text=text.replace(' ', '%s')) os.system(cmd) adb_keyboard_input('hello world') ================================================ FILE: reply/data.json ================================================ { "data":[ "你好,陌生人" ] } ================================================ FILE: requirements.txt ================================================ matplotlib==2.2.0 xlrd==1.1.0 pandas==0.22.0 numpy==1.14.1 Pillow==5.1.0 scikit-learn==0.19.1