Python模拟屏幕点击自动完成词达人任务(附源码)

Python模拟屏幕点击自动完成微信词达人任务

  • 该贴是以微信词达人为基础实践而写,如果我们并没有使用词达人,该源码中关键代码部分和模拟点击原理希望对大家有帮助。

某度API申请

  • 方便大家观看体验,申请方法留在文章末尾

视频演示地址查看演示,或者查看演示


过程解析

对词达人自动点击完成任务我分为以下几个步骤

  1. 将词达人窗口放置指定位置

理论python有方法自动找到窗口但是像词达人比较好控制的我们手动放置,这样容错率大大提高

  • 我的电脑分辨率为1920*1080(如何查看分辨率:设置->系统->显示)
  • 我们将词达人窗口防止左侧高度拉满,宽度最小为以下状态,使用截图软件截图后词达人窗口大小为480*1040
    在这里插入图片描述
  1. 对词达人窗口进行截图
#抓取图片   #pcname为保存的文件名
def getPc(pcname):
    hwnd = 0 # 窗口的编号,0号表示当前活跃窗口
    # 根据窗口句柄获取窗口的设备上下文DC(Divice Context)
    hwndDC = win32gui.GetWindowDC(hwnd)
    # 根据窗口的DC获取mfcDC
    mfcDC = win32ui.CreateDCFromHandle(hwndDC)
    # mfcDC创建可兼容的DC
    saveDC = mfcDC.CreateCompatibleDC()
    # 创建bigmap准备保存图片
    saveBitMap = win32ui.CreateBitmap()
    # 获取监控器信息
    MoniterDev = win32api.EnumDisplayMonitors(None, None)
    w = 480		# w,h   #图片大小
    h = 1040
    # 为bitmap开辟空间
    saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
    # 高度saveDC,将截图保存到saveBitmap中
    saveDC.SelectObject(saveBitMap)
    # 截取从左上角(0,0)长宽为(w,h)的图片
    saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)
    saveBitMap.SaveBitmapFile(saveDC, pcname)

python有很多方法对屏幕截图哦,大家可以好好研究研究

  • 这是我使用代码截图后在编辑器看到的效果
    在这里插入图片描述
  1. 使用某度API对截取的图片进行文字识别和信息识别(坐标信息)

如果使用orc等其它开源的识别方法次数不限但是太过依赖环境,直接调用api较为简单但是使用次数有限

# 使用百度Api对文件(图片)进行识别,response.json()包含文字位置信息
    f = open(pcname, 'rb')
    img = base64.b64encode(f.read())
    params = {"image":img}
    access_token = ACCESS_TOKEN
    request_url = request_url + "?access_token=" + access_token
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    response = requests.post(request_url, data=params, headers=headers)
    print(response.json())

返回(部分)参数如下:表示识别了scre这个单词,单词文字像素高宽为40*14,在图片中的坐标为 (106,446)
在这里插入图片描述

  1. 根据我之前的获取词达人答案原理,将获取到的答案与识别的文字进行比对,比对到正确的文字时,记下位置
  2. 在屏幕中模拟点击记录的位置

视频演示地址:


源码(有些包没有需要pip install)

import sys
import pyautogui
import winsound
import operator
from pymouse import PyMouse
import requests
import base64
import os
import json
import time
import time
import win32gui, win32ui, win32con, win32api

type = 0
lodec = 'C:\\responseBody.txt'

APP_ID = '*****' # 刚才获取的 ID,下同
API_KEY = '******'
SECRECT_KEY = '******'
ACCESS_TOKEN = '你生成的access_token'

#获取token
#第一次使用请先在main中调用一次getToken(),将其返回值access_token填到全局变量ACCESS_TOKEN 中
def getToken():
    # client_id 为官网获取的AK, client_secret 为官网获取的SK
    host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + API_KEY + '&client_secret=' + SECRECT_KEY 
    response = requests.post(host)
    if response:
        return response.json().access_token

def init():
    print("=====================词达人小工具3.0=====================\n\n")
    time.sleep(1)
    print('第一次使用请先在main中调用一次getToken(),将其返回值access_token填到全局变量ACCESS_TOKEN 中')
    if os.path.getsize(lodec) == 0:
        print("没有在C盘中找到资源,检查办法:\n(1):手动答题一道然后再打开本程序(前面的听力部分不算)\n(2):查看C盘下是否存在responseBody.txt文件\n(3):检查Fidder配置\n程序将在10秒后自动退出")
        time.sleep(10)
        exit()
    print("资源检查成功,开始使用\n请将该窗口放置合适位置\n程序会每10题暂停3秒,3秒期间你可以操作你的电脑")
    time.sleep(1)

#读取答案
def getAnswer():
    print('搜寻答案....')
    answers = []
    data = json.loads(open(lodec, "r", encoding='utf-8').read());
    #多选
    if data['data']['topic_mode'] in [31] :
        options = data['data']['options']
        for option in options:
            if option['answer']==True :
                answers.append(option['content'])
    #单选
    if data['data']['topic_mode'] in [11,22,42] :
        options = data['data']['options']
        for option in options:
            if option['answer']==True :
                answers.append(option['content'].replace(' ', '').replace(';', ';').replace(',', ',').replace('.', '').replace('…', ''))
    #选词
    if data['data']['topic_mode'] in [32] :
        options = data['data']['answer_content']['answer_arr']
        for option in options:
            #print(option)
            answers.append(option)
    #填空
    if data['data']['topic_mode'] in [51] :
        type = 1
        answers.append(data['data']['answer_content'])
    for a in answers:
        print(a)
    return answers


#抓取图片
def getPc(pcname):
    hwnd = 0 # 窗口的编号,0号表示当前活跃窗口
    # 根据窗口句柄获取窗口的设备上下文DC(Divice Context)
    hwndDC = win32gui.GetWindowDC(hwnd)
    # 根据窗口的DC获取mfcDC
    mfcDC = win32ui.CreateDCFromHandle(hwndDC)
    # mfcDC创建可兼容的DC
    saveDC = mfcDC.CreateCompatibleDC()
    # 创建bigmap准备保存图片
    saveBitMap = win32ui.CreateBitmap()
    # 获取监控器信息
    MoniterDev = win32api.EnumDisplayMonitors(None, None)
    w = 480
    h = 1040
    # w,h   #图片大小
    # 为bitmap开辟空间
    saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
    # 高度saveDC,将截图保存到saveBitmap中
    saveDC.SelectObject(saveBitMap)
    # 截取从左上角(0,0)长宽为(w,h)的图片
    saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)
    saveBitMap.SaveBitmapFile(saveDC, pcname)

#文字位置
def getPosition(answers, pcname):
    positions = []
    request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general"
    # 二进制方式打开图片文件
    f = open(pcname, 'rb')
    img = base64.b64encode(f.read())
    params = {"image":img}
    access_token = ACCESS_TOKEN
    request_url = request_url + "?access_token=" + access_token
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    response = requests.post(request_url, data=params, headers=headers)
    if response:
        for r in response.json()['words_result']:
            flag = False
            #如果包含中文
            for ch in r['words']:
                if u'\u4e00' >= ch or ch >= u'\u9fff':
                    flag = True
            if flag:
                w = r['words'][4:].replace('.', '')
            else:
                w = r['words']
            for a in answers:
                if w.find(str(a)) != -1 or str(a).find(w) != -1:
                    tu = [r['location']['left'], r['location']['top']]
                    positions.append(tu)
    return positions

#屏幕点击答题
def makeAnswer(positions):
    m = PyMouse()
    for p in positions:
        #m.move(p[0], p[1])
        m.click(p[0], p[1])  #移动并且在(x,y)位置左击
        time.sleep(0.5)
        m.click(400,1000)
        
if __name__ == "__main__":
    pcname = 'answers.jpg'
    init()
    i = 0
    while True:
        i += 1
        #获取正确答案集合
        answers = getAnswer()
        #截取图片
        getPc(pcname)
        #根据正确答案找到答案位置
        positions = getPosition(answers, pcname)
        #点击
        makeAnswer(positions)
        #每10题停留3秒:避免不可控
        if i>10:
            time.sleep(3)
            print("-------------暂停时期:3秒后继续答题-----------\n\n\n")
            i = 0

某度API申请

在这里插入图片描述
随便填就行
在这里插入图片描述

立即创建后查看
下面这三个东西放到代码里就可以了
在这里插入图片描述

发布了16 篇原创文章 · 获赞 9 · 访问量 3771

猜你喜欢

转载自blog.csdn.net/SR02020/article/details/105497043
今日推荐