
一、背景需求
园园通8月7日前搭建托小班班级栏目,绑定教师,幼儿分班(以前至少都要8月20日以后操作)

打开园园通,发现小班的孩子数据已经进园园通
由于没有搭建新小班栏目,所以这些幼儿无法直接进入班级,需要人工分班。
我先手动搭建了班级

在手动搭建班级的时候,这个改版后的园园通,操作起来步骤比较多,有点繁琐。好不容易做完文件夹。
又做了大6班孩子的人工分班(转入其他大班)也是累死。
二、Python分班
(一)园园通分班的界面样式


这125人的分班我再也不想一条条做手工做了。

准备写程序,读取表单,自动分班
(二)制作收集表单
1.制作收集表
这个项目里有一个“制作表单”的代码,拿来用。

【办公类-109-01】20250728托小班新生圆形挂牌(学号姓名)9.4CM
https://mp.csdn.net/mp_blog/creation/editor/149722959
原始代码+修改班级名称,

'''
制作班级幼儿信息收集表,包含学号、园区、班级、姓名、性别
豆包,阿夏
20250728
'''
import pandas as pd
import openpyxl
def create_class_excel(file_path):
# 班级配置:(班级名称,园区,人数)
class_config = [
# 一分园
("托1班", "一分园", 20),
("托2班", "一分园", 20),
# 二分园
("托3班", "二分园", 20),
("小1班", "二分园", 25),
("小2班", "二分园", 25),
("小3班", "二分园", 25),
# 一分园
("小4班", "一分园", 25),
("小5班", "一分园", 25),
# 总园 中班1‑6班
("中1班", "总园", 30),
("中2班", "总园", 30),
("中3班", "总园", 30),
("中4班", "总园", 30),
("中5班", "总园", 30),
("中6班", "总园", 30),
# 总园 大班1‑5班
("大1班", "总园", 35),
("大2班", "总园", 35),
("大3班", "总园", 35),
("大4班", "总园", 35),
("大5班", "总园", 35),
]
with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
# 通用模板页,最大人数35
max_num = 35
template_data = {
"学号": list(range(1, max_num + 1)),
"园区": [""] * max_num,
"班级": [""] * max_num,
"姓名": [""] * max_num,
"性别": [""] * max_num
}
template_df = pd.DataFrame(template_data)
template_df.to_excel(writer, sheet_name="模板", index=False)
for cls_name, garden_name, stu_count in class_config:
df_data = {
"学号": list(range(1, stu_count + 1)),
"园区": [garden_name] * stu_count,
"班级": [cls_name] * stu_count,
"姓名": [""] * stu_count,
"性别": [""] * stu_count
}
df = pd.DataFrame(df_data)
df.to_excel(writer, sheet_name=cls_name, index=False)
print(f"已创建工作表: {cls_name} | 园区:{garden_name} | 人数:{stu_count}")
print(f"\nExcel文件已生成: {file_path}")
if __name__ == "__main__":
path = r'C:\Users\mhjg2\Desktop\20250728托小幼儿挂牌'
excel_file = path + r"\20260805班级信息表.xlsx"
create_class_excel(excel_file)






2.把表单做成多人编辑,共享

急用,我单独做了一个小班的,


3.第二天班主任把班级孩子名字性别都写好了

但是姓名里面有空格,影响识别(张三和张 三)是两个名字

在网络共享编辑里面,批量替换空格、



4.下载,先制作一个分班代码



复制到谷歌浏览器,自动下载到


一定要确保没有空格


必须把空格删除,否则一堆匹配不上的名字


(三)撰写代码
1.研究园园通分班的所有按钮




按钮不多,很方便
2.一个班级的假姓名,测试代码

豆包AI编程



import openpyxl
# 替换为你的文件路径
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260805班级信息表.xlsx"
def get_class_name_info(excel_path):
result = []
# 打开Excel文件
wb = openpyxl.load_workbook(excel_path)
# 遍历所有工作表(每个sheet对应一个班级)
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
# 遍历行,第1行是表头,从第2行开始读取数据
for row in ws.iter_rows(min_row=2, values_only=True):
# 行结构:学号,园区,班级,姓名,性别
student_id, park, class_name, name, gender = row
# 姓名为空/None/空白字符串则跳过
if not name or str(name).strip() == "":
continue
# 存入结果:班级、姓名
result.append({"班级": class_name, "姓名": name})
wb.close()
return result
if __name__ == "__main__":
data = get_class_name_info(file_path)
# 打印提取结果
for item in data:
print(f"班级:{item['班级']},姓名:{item['姓名']}")
# 如需导出到新文件可继续扩展

正确,可以获取班级和姓名
2.Python模拟点击园园通的各种按钮,实现分班。

我记得原来不是这个库,



def集合我还是用不来。

Python点击,需要先自己找每个按钮的坐标,把它写下来


制作一个查找坐标的代码

import pyautogui
import time
print("移动鼠标查看坐标,按 Ctrl+C 停止程序")
time.sleep(3)
# 需要把园园通(火狐100%)界面放大,
# 运行这个代码,然后手动把VS最小化
# 把鼠标点在需要的按钮的位置上,所以要等三秒
x, y = pyautogui.position()
# 实时打印,覆盖上一行输出
print(f"\r当前鼠标坐标 X:{x} Y:{y}", end="")
time.sleep(0.1)
我不想每次都手动最小化VScode,看看能不能自动最小化,



# import pyautogui
# import time
# print("移动鼠标查看坐标,按 Ctrl+C 停止程序")
# time.sleep(3)
# # 需要把园园通(火狐100%)界面放大,
# # 运行这个代码,然后手动把VS最小化
# # 把鼠标点在需要的按钮的位置上,所以要等三秒
# x, y = pyautogui.position()
# # 实时打印,覆盖上一行输出
# print(f"\r当前鼠标坐标 X:{x} Y:{y}", end="")
# time.sleep(0.1)
import pyautogui
import time
import pygetwindow as gw
# 1. 找到VSCode窗口(匹配标题含 Visual Studio Code)
vscode_wins = gw.getWindowsWithTitle("Visual Studio Code")
if not vscode_wins:
print("未找到VSCode窗口,请先打开VSCode再运行!")
else:
win = vscode_wins[0]
# 自动最小化VSCode
win.minimize()
print("VSCode已自动最小化,你有5秒时间移动鼠标到目标位置")
time.sleep(5) # 等待5秒给你放鼠标
# 获取当前鼠标坐标并打印
x, y = pyautogui.position()
# print(f"\n已捕获鼠标坐标:X = {x} , Y = {y}")
print(f"\n已捕获鼠标坐标:{x},{y}")
# 934,354
# 自动最大化VSCode
win.maximize()
print("VSCode已自动最大化,程序结束")
完美,运行后,就自动最小化VSCODE界面,然后手动把鼠标放到指定的按钮上,等5秒,VSCODE界面自动打开,显示打印出来的坐标





import openpyxl
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260805小班园园通分班名单.xlsx"
def get_class_name_info(excel_path):
result = []
wb = openpyxl.load_workbook(excel_path)
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
for row in ws.iter_rows(min_row=2, values_only=True):
# 改用索引,不强制拆5个,兼容列数不够
# 索引:0学号,1园区,2班级,3姓名,4性别
if len(row) <4:
continue # 列太少直接跳过这一行
class_name = row[1]
name = row[2]
# 判断姓名为空就跳过
if not name or str(name).strip() == "":
continue
result.append({"班级": class_name, "姓名": name})
wb.close()
return result
if __name__ == "__main__":
data = get_class_name_info(file_path)
for item in data:
print(f"班级:{item['班级']},姓名:{item['姓名']}")

'''
园园通小班孩子进入后,需要分班
1.收集名单
2.读取名单,提取班级姓名
3.Python模拟鼠标点击园园通按钮,进行分班
'''
import openpyxl
import pyautogui
import time
import pyperclip
import pygetwindow as gw
# 1. 找到VSCode窗口(匹配标题含 Visual Studio Code)
vscode_wins = gw.getWindowsWithTitle("Visual Studio Code")
if not vscode_wins:
print("未找到VSCode窗口,请先打开VSCode再运行!")
else:
win = vscode_wins[0]
# 自动最小化VSCode
win.minimize()
print("VSCode已自动最小化,你有5秒时间移动鼠标到目标位置")
time.sleep(5) # 等待5秒给你放鼠标
import random
# 随机休眠:1~3秒,带小数,模拟真人操作
def rand_sleep():
t = random.uniform(2, 4)
time.sleep(t)
# file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260805班级信息表.xlsx"
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260805小班园园通分班名单.xlsx"
wb = openpyxl.load_workbook(file_path)
# 读取表格
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
for row in ws.iter_rows(min_row=2, values_only=True):
if len(row) < 4:
continue
name = row[2]
if not name or str(name).strip() == "":
continue
class_name = row[1]
# garden_name = row[1]
# data_list.append([class_name, name])
# print(name)
# print(class_name)
# 进入园园通界面
# 点击姓名栏,
pyautogui.click(839,368)
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(name)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 搜索
pyautogui.click(1163,433)
rand_sleep()
# 点击分班
pyautogui.click(1765,619)
rand_sleep()
# 选择园区,如果等于总园,就点击第X个
# pyautogui.click(923,599)
# rand_sleep()
# if garden_name=='总园':
# for i in range(1):
# pyautogui.press('down')# 按下↓
# elif garden_name=='二分园':
# for i in range(2):
# pyautogui.press('down')# 按下↓
# elif garden_name=='一分园':
# for i in range(3):
# pyautogui.press('down')# 按下↓
# pyautogui.press('Enter')# 按回车
# 选择年级,如果等于小班托班或中班大班,就点击第X个(未测试点几下)
# pyautogui.click(923,599)
# time.sleep(1)
# grade_name=class_name[0]+class_name[2]
# if grade_name=='托班':
# for i in range(1):
# pyautogui.press('down')# 按下↓
# elif grade_name=='小班':
# for i in range(2):
# pyautogui.press('down')# 按下↓
# elif grade_name=='中班':
# for i in range(3):
# pyautogui.press('down')# 按下↓
# elif grade_name=='大班':
# for i in range(3):
# pyautogui.press('down')# 按下↓
# pyautogui.press('Enter')# 按回车
# 选择班级,如果等于小1班 小2班 小3班,就点击第X个
pyautogui.click(880,681)
time.sleep(1)
if class_name=='小1班':
for i in range(1):
pyautogui.press('down')# 按下↓
elif class_name=='小2班':
for i in range(2):
pyautogui.press('down')# 按下↓
elif class_name=='小3班':
for i in range(3):
pyautogui.press('down')# 按下↓
elif class_name =='小4班':
for i in range(2):
pyautogui.press('down')# 按下↓
elif class_name=='小5班':
for i in range(1):
pyautogui.press('down')# 按下↓
pyautogui.press('Enter')# 按回车
rand_sleep()
# 确认,回到最初的界面
pyautogui.click(1184,795)
rand_sleep()
# 清空名字点击×
pyautogui.click(1049,376)
rand_sleep()
wb.close()
# 自动最大化VSCode
win.maximize()
print("VSCode已自动最大化,程序结束")
前期分班,也遇到过“教师输入的名字”与“园园通的名字”不同,识别不了。这个程序如果出现识别不到的人,还是会默认各种点击,但是不影响,不遮挡界面,10秒后就会再次写入下一个名字
三、测试中遇到的问题
1.从删除名字,改成重置名字

张X这个孩子存在的,就是没有来得及删除×


'''
园园通小班孩子进入后,需要分班
1.收集名单
2.读取名单,提取班级姓名
3.Python模拟鼠标点击园园通按钮,进行分班
'''
import openpyxl
import pyautogui
import time
import pyperclip
import pygetwindow as gw
# 1. 找到VSCode窗口(匹配标题含 Visual Studio Code)
vscode_wins = gw.getWindowsWithTitle("Visual Studio Code")
if not vscode_wins:
print("未找到VSCode窗口,请先打开VSCode再运行!")
else:
win = vscode_wins[0]
# 自动最小化VSCode
win.minimize()
print("VSCode已自动最小化,你有5秒时间移动鼠标到目标位置")
time.sleep(5) # 等待5秒给你放鼠标
import random
# 随机休眠:1~3秒,带小数,模拟真人操作
def rand_sleep():
t = random.uniform(2, 4)
time.sleep(t)
# file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260805班级信息表.xlsx"
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260805小班园园通分班名单.xlsx"
wb = openpyxl.load_workbook(file_path)
# 读取表格
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
for row in ws.iter_rows(min_row=2, values_only=True):
if len(row) < 4:
continue
name = row[2]
if not name or str(name).strip() == "":
continue
class_name = row[1]
# garden_name = row[1]
# data_list.append([class_name, name])
# print(name)
# print(class_name)
# 进入园园通界面
# 点击姓名栏,
pyautogui.click(839,368)
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(name)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 搜索
pyautogui.click(1163,433)
rand_sleep()
# 点击分班
pyautogui.click(1765,619)
rand_sleep()
# 选择园区,如果等于总园,就点击第X个
# pyautogui.click(923,599)
# rand_sleep()
# if garden_name=='总园':
# for i in range(1):
# pyautogui.press('down')# 按下↓
# elif garden_name=='二分园':
# for i in range(2):
# pyautogui.press('down')# 按下↓
# elif garden_name=='一分园':
# for i in range(3):
# pyautogui.press('down')# 按下↓
# pyautogui.press('Enter')# 按回车
# 选择年级,如果等于小班托班或中班大班,就点击第X个(未测试点几下)
# pyautogui.click(923,599)
# time.sleep(1)
# grade_name=class_name[0]+class_name[2]
# if grade_name=='托班':
# for i in range(1):
# pyautogui.press('down')# 按下↓
# elif grade_name=='小班':
# for i in range(2):
# pyautogui.press('down')# 按下↓
# elif grade_name=='中班':
# for i in range(3):
# pyautogui.press('down')# 按下↓
# elif grade_name=='大班':
# for i in range(3):
# pyautogui.press('down')# 按下↓
# pyautogui.press('Enter')# 按回车
# 选择班级,如果等于小1班 小2班 小3班,就点击第X个
pyautogui.click(880,681)
time.sleep(1)
if class_name=='小1班':
for i in range(1):
pyautogui.press('down')# 按下↓
elif class_name=='小2班':
for i in range(2):
pyautogui.press('down')# 按下↓
elif class_name=='小3班':
for i in range(3):
pyautogui.press('down')# 按下↓
elif class_name =='小4班':
for i in range(2):
pyautogui.press('down')# 按下↓
elif class_name=='小5班':
for i in range(1):
pyautogui.press('down')# 按下↓
pyautogui.press('Enter')# 按回车
rand_sleep()
# 确认,回到最初的界面
pyautogui.click(1184,795)
rand_sleep()
# # 清空名字点击×
# pyautogui.click(1049,376)
# rand_sleep()
# 清空名字点重制
pyautogui.click(1259,443)
rand_sleep()
wb.close()
# 自动最大化VSCode
win.maximize()
print("VSCode已自动最大化,程序结束")
2.程序中断的处理
邓和张的情况,导致程序打断了,如果重新运行,就会从第一个开始(已经做过了,只显示“查看功能”)






运行后15行,还是张X,由于张X已经运行做过了,右侧不是“查看、分班、转出”。而只有一个“查看”。程序就点击的“查看”,但是弹出的查看表里面没有确认按钮,弹出的表一直悬浮,无法继续“重置”,写入第二人姓名


弹出的表,没有关闭按钮(右上角X关闭)

改成从16行开始
'''
园园通小班孩子进入后,需要分班
1.收集名单
2.读取名单,提取班级姓名
3.Python模拟鼠标点击园园通按钮,进行分班
'''
import openpyxl
import pyautogui
import time
import pyperclip
import pygetwindow as gw
# 1. 找到VSCode窗口(匹配标题含 Visual Studio Code)
vscode_wins = gw.getWindowsWithTitle("Visual Studio Code")
win = None
if not vscode_wins:
print("未找到VSCode窗口,请先打开VSCode再运行!")
else:
win = vscode_wins[0]
# 自动最小化VSCode
win.minimize()
print("VSCode已自动最小化,你有5秒时间移动鼠标到目标位置")
time.sleep(5) # 等待5秒给你放鼠标
import random
# 随机休眠:2~4秒,带小数,模拟真人操作
def rand_sleep():
t = random.uniform(2, 4)
time.sleep(t)
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260805小班园园通分班名单.xlsx"
wb = openpyxl.load_workbook(file_path)
# 读取表格
for idx_sheet, sheet_name in enumerate(wb.sheetnames):
ws = wb[sheet_name]
# 第一张工作表从15行开始;其他工作表跳过表头从第2行开始
if idx_sheet == 0:
start_row = 16
print(f"【第一张表 {sheet_name}】从Excel第15行开始处理")
else:
start_row = 2
print(f"【工作表 {sheet_name}】跳过表头,从第2行开始")
for row in ws.iter_rows(min_row=start_row, values_only=True):
if len(row) < 4:
continue
name = row[2]
if not name or str(name).strip() == "":
continue
class_name = row[1]
print(f"正在处理:姓名={name},班级={class_name}")
# 点击姓名栏
pyautogui.click(839,368)
pyperclip.copy(name)
pyautogui.hotkey("ctrl", "v")
rand_sleep()
# 搜索
pyautogui.click(1163,433)
rand_sleep()
# 点击分班
pyautogui.click(1765,619)
rand_sleep()
# 选择班级下拉
pyautogui.click(880,681)
rand_sleep()
if class_name == '小1班':
for i in range(1):
pyautogui.press('down')
elif class_name == '小2班':
for i in range(2):
pyautogui.press('down')
elif class_name == '小3班':
for i in range(3):
pyautogui.press('down')
elif class_name == '小4班':
for i in range(2):
pyautogui.press('down')
elif class_name == '小5班':
for i in range(1):
pyautogui.press('down')
pyautogui.press('Enter')
rand_sleep()
# 确认保存
pyautogui.click(1184,795)
rand_sleep()
# 重置表单
pyautogui.click(1259,443)
rand_sleep()
wb.close()
if win is not None:
win.maximize()
print("VSCode已自动最大化,程序结束")
2.“保存”后有延时,需要拉长保存时间
感觉修改后确认 ,退出弹框的时间2-4秒不行,要固定5秒(有延时)

测试小1班最后一个孩子,结果没有此人

没有这个孩子,程序会自动点击,各种按钮,最后还是可以进入下一个界面。但是我可能会不清楚这个孩子没有遍历过。

Python不如uibot能识别图像,进行判断并写出这个孩子。只能默默等它全部点完。执行下一个名字。
(四)合计用时——40分钟
125调数据,我设置的延时2-4秒随机,所以一个孩子也要20-30分钟,加上中间有2次修改大约20分钟,所以实际用40分钟左右,完成分班。

(五)问题名字。
所有孩子都分班后,还剩两个孩子。查询名单,看到相似的名字
1、输入字:同音字,外形不同——以“园园通名字”为准


3.“煕”(断开)和“熙”(粘合)
还有一个孩子,教师写的名字和园园通的名字看上去一样,我不能理解为什么excle不能识别

最后,我把两个字放大,仔细看:“臣”里面的左竖,有点断开
下面的“熙”不断开



这两个字实在太像了,并且字库都存在,通常不会有家长给孩子取“断开的煕”,所以我们默认就是班主任手打名字的时候选错了“熙”。

只有Python程序识别出来字体细微差异,肉眼根本看不出差异。
(五)分班完成(幼儿右侧显示查看,而不是分班),每个班级25人


四、制作18个班级总表
最后把小班的信息复制到18个班级的总表里,便于游戏做点名册——哭,今年减了2个班,孩子人数越来越少了。

检查其他年级老师填写的内容,有的老师为了好看,两个名字中间有空格,但是我还是把他们都取消。因为幼儿收据账单上不会有空格。

差不多,现在两个名字的孩子真少,

两张多人编辑,一张小班园园通插班表,一张19个班级信息合并表。小班表我不想用了。向取消掉。
豆包给的方案


把小班收集表变成查看,这样就不能再编辑了。默认作废。

&spm=1001.2101.3001.5002&articleId=163511702&d=1&t=3&u=6c47c3cf6e1e41a2aca7f04d3cc21858)
329

被折叠的 条评论
为什么被折叠?



