在本文中,我们将分享一段通过Python实现批量管理学生作业并自动回复的代码。此代码结合了微信企业版的自动化操作、Excel文件的读取与写入以及图像识别技术,旨在提高工作效率,减少重复劳动。无论是教育工作者还是任何需要处理大量信息的人员,都可以利用这段代码来简化日常任务。
项目概述
这个Python脚本主要实现以下几个功能:
- 更新学生数据:通过读取Excel文件,更新学生的作业提交状态及发送次数。
- 自动回复学生消息:利用企业微信搜索学生姓名并发送作业信息。
- 图像识别与自动点击:通过图像识别技术定位到微信界面中的按钮或输入框,自动执行相应操作。
我们将逐步讲解代码中的各个部分,帮助你理解它的原理与实现过程。
项目所需库
在开始之前,我们需要确保以下Python库已经安装:
- openpyxl:用于操作Excel文件。
- pyautogui:用于控制鼠标和键盘,模拟人类的操作。
- pyperclip:用于剪贴板操作。
- pandas:用于读取和处理数据。
- time 和 datetime:用于时间控制。
你可以通过以下命令安装必要的库:
pip install openpyxl pyautogui pyperclip pandas
代码解析
1. 更新学生数据(update_student_data
函数)
该函数的主要功能是更新Excel表格中的学生作业提交状态。
def update_student_data(student_name, message, root_path):
# 加载已存在的 Excel 文件
wb = openpyxl.load_workbook(root_path + "/excel/py12/urge_student.xlsx")
ws = wb.active
# 获取当前日期,格式为 "YYYY/MM/DD"
current_date = datetime.now().strftime("%Y/%m/%d")
# 遍历表格的每一行,查找指定的学生姓名
for row in range(2, ws.max_row + 1): # 假设第一行是表头,从第二行开始
name = ws[f'A{row}'].value # 姓名列(假设是 A 列)
# 如果找到了匹配的姓名
if name == student_name:
current_time_cell = f'E{row}' # 当前时间列(假设是 E 列)
send_count_cell = f'F{row}' # 发送次数列(假设是 F 列)
# 获取当前行的当前时间和发送次数
current_time_value = ws[current_time_cell].value
send_count_value = ws[send_count_cell].value
# 判断是否满足条件
if current_time_value != current_date or send_count_value != 1:
# 如果不等于当前时间或者发送次数不为 1,则更新这两列数据
ws[current_time_cell] = current_date # 将当前时间填入 E 列
ws[send_count_cell] = 1 # 将发送次数填为 1
pyperclip.copy(student_name)
pg.hotkey('ctrl', 'v')
time.sleep(0.5)
pg.press('enter')
time.sleep(1)
pyperclip.copy(message)
pg.hotkey('ctrl', 'v')
pg.press('enter')
print(f"学生 {student_name} 的数据已更新!")
else:
print(f"学生 {student_name} 的数据已符合要求,无需更新。")
break
else:
print(f"未找到名为 {student_name} 的学生!")
# 保存更新后的 Excel 文件
wb.save(root_path + "/excel/py12/urge_student.xlsx")
print("文件已保存。")
解析:
- 读取Excel:通过
openpyxl
库加载Excel文件,获取活动工作表。 - 遍历查找学生:在Excel中遍历每一行,找到指定学生的姓名,并读取其当前时间和发送次数。
- 条件判断与更新:如果当前时间和发送次数不符合要求,就更新Excel中的数据,并通过模拟键盘操作发送消息。
2. 自动回复学生消息(reply_stu
函数)
该函数的作用是自动回复指定学生的消息。它通过模拟键盘和鼠标操作来实现这一功能。
def reply_stu(self, name, message):
"""
:param name: 学生名字 通过搜索栏能搜到的值
:param message: 需要发的消息
:return: 无返回值 封装的是回复学生的操作
"""
click_image(self.cancel_image_path) # 点击取消按钮,确保没有其他窗口阻挡
try:
time.sleep(0.5)
loc_wx_search = pg.locateCenterOnScreen(self.root_path + '/img/work_search.png', confidence=0.9)
pg.click(loc_wx_search, duration=0.5)
time.sleep(1)
except:
print('没找到企业微信里的搜索框')
update_student_data(name, message, self.root_path)
解析:
- 图像识别与点击:使用
pyautogui.locateCenterOnScreen
函数来定位图像(例如,搜索框图标),并点击该位置来打开微信搜索框。 - 更新学生数据:通过
update_student_data
函数更新学生信息后,自动发送消息。
3. 打开企业微信聊天框(open_ComWC
函数)
这个函数的作用是通过模拟操作打开企业微信聊天界面,并将消息发送到对应的学生。
def open_ComWC(self):
"""
打开微信聊天框
:return: 无返回值
"""
time.sleep(5)
try:
loc_search = pg.locateCenterOnScreen(self.root_path + '/img/com_search.png', confidence=0.9)
pg.click(loc_search, duration=0.5)
time.sleep(1)
except:
print('未找到搜索框')
pyperclip.copy('企业微信')
pg.hotkey('ctrl', 'v')
解析:
- 模拟点击操作:首先等待5秒钟确保企业微信窗口已打开,然后通过图像识别定位到搜索框,并模拟点击操作来打开聊天界面。
- 发送消息:通过
pyperclip.copy
将消息复制到剪贴板,再使用pg.hotkey('ctrl', 'v')
粘贴并发送。
4. 图像识别与点击(click_image
函数)
这个函数用于在屏幕上查找并点击特定的图像。
def click_image(image_path):
try:
# 尝试查找图像
image_location = pyautogui.locateCenterOnScreen(image_path, confidence=0.8)
if image_location:
pyautogui.click(image_location)
else:
print("图像未找到")
except Exception as e:
print(f"无法找到图像,执行后续操作{e}")
解析:
- 图像查找与点击:通过
pyautogui.locateCenterOnScreen
定位图像并模拟点击操作,如果未找到图像,则打印错误信息。
完整代码实现
import collections
import json
import os
import random
import time
import openpyxl
import pandas as pd
import pyautogui
import pyperclip
import pyautogui as pg
from datetime import datetime
APP_TITLE = u'批量发送作业'
APP_ICON = 'img/top.ico'
row_name = '学生姓名'
row_reply = '回复'
def update_student_data(student_name, message, root_path):
# 加载已存在的 Excel 文件
wb = openpyxl.load_workbook(root_path + "/excel/py12/urge_student.xlsx")
ws = wb.active
# 获取当前日期,格式为 "YYYY/MM/DD"
current_date = datetime.now().strftime("%Y/%m/%d")
# 遍历表格的每一行,查找指定的学生姓名
for row in range(2, ws.max_row + 1): # 假设第一行是表头,从第二行开始
name = ws[f'A{row}'].value # 姓名列(假设是 A 列)
# 如果找到了匹配的姓名
if name == student_name:
current_time_cell = f'E{row}' # 当前时间列(假设是 E 列)
send_count_cell = f'F{row}' # 发送次数列(假设是 F 列)
# 获取当前行的当前时间和发送次数
current_time_value = ws[current_time_cell].value
send_count_value = ws[send_count_cell].value
# 判断是否满足条件
if current_time_value != current_date or send_count_value != 1:
# 如果不等于当前时间或者发送次数不为 1,则更新这两列数据
ws[current_time_cell] = current_date # 将当前时间填入 E 列
ws[send_count_cell] = 1 # 将发送次数填为 1
pyperclip.copy(student_name)
pg.hotkey('ctrl', 'v')
time.sleep(0.5)
pg.press('enter')
time.sleep(1)
pyperclip.copy(message)
pg.hotkey('ctrl', 'v')
pg.press('enter')
print(f"学生 {student_name} 的数据已更新!")
else:
print(f"学生 {student_name} 的数据已符合要求,无需更新。")
break
else:
print(f"未找到名为 {student_name} 的学生!")
# 保存更新后的 Excel 文件
wb.save(root_path + "/excel/py12/urge_student.xlsx")
print("文件已保存。")
def click_image(image_path):
try:
# 尝试查找图像
image_location = pyautogui.locateCenterOnScreen(image_path, confidence=0.8)
if image_location:
pyautogui.click(image_location)
else:
print("图像未找到")
except Exception as e:
print(f"无法找到图像,执行后续操作{e}")
# 执行其他操作
class Homework:
def __init__(self, root_path):
self.root_path = root_path
self.cancel_image_path = root_path + '/img/cancel.png'
start_time = time.strftime('%Y%m%d')
def check_wxwork(self):
"""
检查微信聊天框是否出现 判断原理:判断“聊天标签”图片在不在屏幕中
:return: bool类型值 可通过while进行阻塞保证微信聊天框出现再运行程序
"""
try:
time.sleep(0.5)
pg.locateCenterOnScreen(self.root_path + '/img/check_wxwork.png', confidence=0.9)
return False
except:
return True
def reply_stu(self, name, message):
"""
:param name: 学生名字 通过搜索栏能搜到的值
:param message: 需要发的消息
:return: 无返回值 封装的是回复学生的操作
"""
click_image(self.cancel_image_path)
try:
time.sleep(0.5)
loc_wx_search = pg.locateCenterOnScreen(self.root_path + '/img/work_search.png', confidence=0.9)
pg.click(loc_wx_search,duration=0.5)
time.sleep(1)
except:
print('没找到企业微信里的搜索框')
update_student_data(name, message, self.root_path)
def open_ComWC(self):
"""
打开微信聊天框
:return: 无返回值
"""
time.sleep(5)
# print(self.root_path + '/img/com_search.png')
try:
loc_search = pg.locateCenterOnScreen(self.root_path + '/img/com_search.png', confidence=0.9)
pg.click(loc_search, duration=0.5)
time.sleep(1)
except:
print('未找到搜索框')
pyperclip.copy('企业微信')
pg.hotkey('ctrl', 'v')
pg.press('enter')
def oper_excel(self, path):
"""
根据指定格式进行excel的处理
:param path: excel路径
:return: 返回处理过后的字典,字典格式为:{'学生名字': [未完成的作业]}
"""
df = pd.read_excel(path).fillna(0)
dict1 = collections.defaultdict()
for index, row in df.iterrows():
dict1[row[ row_name]] = []
for i in range(1, len(row)):
if row[i] != '√':
dict1[row[ row_name]].append(i)
with open(self.root_path + f'/source/data_{self.start_time}.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(dict1, ensure_ascii=False, indent=4))
return dict1
def askfor_pos(self, path):
def deal_sheet(df, json_demo):
for index, row in df.iterrows():
print(type(row[ row_name]),row[ row_name])
if len(row[ row_name]) == 2:
str_demo = row[row_reply]
# str_demo = row[row_name] + "同学,找不到作业提交的同学也可以点击这个链接直接进入小鹅通作业提交入口https://appya03xmbc7655.h5.xiaoeknow.com/p/t/v1/exam/h5_evaluation/exercise/introduce/eyJleGVyY2lzZV9ib29rX2lkIjoiZTY3MzZlOWExYWY4YWZfT1lPYVhnbkkiLCJleGVyY2lzZV9pZCI6ImV4NjczNmU5YTFjOWNkZl9uNjNHc3NWViJ9?from=eCourse&product_id=course_2oq6vp31oZdsthpUSiABm2zoLHP&sub_course_id="
else:
str_demo = row[row_reply]
# str_demo = row[row_name] + "同学,找不到作业提交的同学也可以点击这个链接直接进入小鹅通作业提交入口https://appya03xmbc7655.h5.xiaoeknow.com/p/t/v1/exam/h5_evaluation/exercise/introduce/eyJleGVyY2lzZV9ib29rX2lkIjoiZTY3MzZlOWExYWY4YWZfT1lPYVhnbkkiLCJleGVyY2lzZV9pZCI6ImV4NjczNmU5YTFjOWNkZl9uNjNHc3NWViJ9?from=eCourse&product_id=course_2oq6vp31oZdsthpUSiABm2zoLHP&sub_course_id="
json_demo[row[row_name]] = str_demo
res_json = {}
sheets = ['Sheet']
dfs = pd.read_excel(path, sheet_name=sheets)
for sheet_name, df in dfs.items():
if sheet_name == sheets[0]:
res_json['1'] = {}
deal_sheet(df, res_json['1'])
elif sheet_name == sheets[1]:
res_json['2'] = {}
deal_sheet(df, res_json['2'])
else:
res_json['3'] = {}
deal_sheet(df, res_json['3'])
with open(self.root_path + f'/source/askfor_{self.start_time}.json', 'w', encoding='utf-8') as f:
json.dump(res_json, f, indent=4, ensure_ascii=False)
return res_json
# 新添加
def askforreply(root_path, path):
"""
回复主函数
:param path: 已完成作业学生excel文件路径
:return:
"""
hw = Homework(root_path)
res_json = hw.askfor_pos(path=path)
print(res_json)
# raise
for key, value in res_json.items():
if key == '1':
hw.open_ComWC()
while hw.check_wxwork():
time.sleep(1)
print('===')
pass
for i, j in value.items():
hw.reply_stu(i, j)
总结
通过以上的功能实现,我们可以使用Python自动化处理学生的作业管理任务。该代码结合了图像识别、Excel数据处理和自动化操作,使得重复的任务更加高效。这不仅提高了工作效率,还为需要进行大量操作的任务提供了便利。无论是教育工作者,还是其他需要进行批量管理的人员,都可以根据需要修改和扩展此代码,满足更多的自动化需求。
希望本篇博客能够帮助你更好地理解如何结合Python进行任务自动化,并鼓励你探索更多类似的应用。