一、背景需求:
前期园园通小班幼儿进入园园通后,因为没有构建小班班级,所以需要人工分班,同时外地户籍的幼儿的户籍地址省市区、户籍地址都要补全。
为了取消标红,我把户籍地址的"市""区"默认为选项第一个,地址写入"待补充"
【办公类110-04】20260806园园通小班分班后"待处理问题"(批量信息、默认省市区、待添加地址)
https://mp.csdn.net/mp_blog/creation/editor/163531430
后来小班班主任收集到幼儿的户籍地址、省市区信息。我也用Python程序把"待补充"改成了"真实地址"
【办公类110-05】20260807园园通小班"待补充"户籍地址自动修改成为真实地址(Python+EXCEL)
https://mp.csdn.net/mp_blog/creation/editor/163557657
二、存在问题:
户口地址是真的,户口所在省是真的,但是户口所在市、户口所在区县都是默认第一个,是不正确。
但是前期检查过"户口所在城市""户口所在"区县"必须手选
这就比较麻烦了。
三、解决思路:
(一)将表单收集小班幼儿双地址的头部,组合上"省市区"。变成一个完整的户籍地址。
1.思路
2.代码
'''
班主任收集的接龙表单(幼儿户籍地址收集)
把6个小班的Excel合并一起
豆包,阿夏
202060821
'''
import os
import pandas as pd
# 文件夹路径
path=r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260821园园通小班双地址修改"
folder_path =path + r"\00收集表单"
# 存放合并后数据
all_data = []
# 遍历文件夹下所有excel文件
for filename in os.listdir(folder_path):
if filename.endswith((".xlsx", ".xls")):
file_full = os.path.join(folder_path, filename)
# 读取excel,第一份保留表头,后续文件跳过表头header=1
df = pd.read_excel(file_full)
if len(all_data) == 0:
# 第一个文件,完整读取,包含标题行
all_data.append(df)
else:
# 后面文件跳过第1行标题
df_no_header = pd.read_excel(file_full, header=1)
all_data.append(df_no_header)
# 全部合并
result = pd.concat(all_data, ignore_index=True)
# 输出合并后的文件
result.to_excel(path +r"\01 小班户籍地址合并结果.xlsx", index=False)
print("合并完成,输出:合并结果.xlsx")
这样斜着排列的
5张表里面有2张模版的确不同,根据豆包知识,不要复制任何"标题栏",否则它会根据内容归类在一列里
'''
班主任收集的接龙表单(幼儿户籍地址收集)
把6个小班的Excel合并一起(每张表的样式不完全相同,合并时抛弃标题栏,否则会斜着排列)
豆包,阿夏
202060821
'''
import os
import pandas as pd
path=r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260821园园通小班双地址修改"
folder_path = path + r"\00收集表单"
all_data = []
for filename in os.listdir(folder_path):
if filename.endswith((".xlsx",".xls")):
full_path = os.path.join(folder_path, filename)
# header=None 不识别表头
df_raw = pd.read_excel(full_path, header=None)
# 删除全部是空的列,消除左侧空白,解决斜错位
df_raw = df_raw.dropna(axis=1, how="all")
# !!跳过第1行标题,只取数据行,所有文件统一去掉第一行
df_data = df_raw.iloc[1:, :].copy()
all_data.append(df_data)
# 合并全部数据,不设置列名
result = pd.concat(all_data, ignore_index=True)
# 输出,不带任何表头
result.to_excel(path+r"\01 小班户籍地址合并结果.xlsx", index=False, header=False)
print("✅合并完成!所有文件已删除标题行,只有纯数据")
用三种表单收集的(不同的列)
手工整理一下
有的家长写了全地址,有的没有全地址,所以还是要人工调整
手动合并了,复制黏贴值,再检查一遍
居右,升序,看看缺不缺"室"
居左,看看少不少"省""市"
最后保留一列户籍地址
(二)园园通下载已有的小班的所有信息,把现居地址提取出来,修改整理出完整的、简短的居住地址。
只要居住地址
放在一起,改名"园园通小班"
复制一次
做假模版,附件上传用
做真数据
'''
小班幼儿户籍地址:教师接龙表单收集的家长填写的户籍地址(包含省市区),手动修改调整正确的完整的全部户籍地址
小班幼儿居住地址:从园园通下载"姓名""现居地址",Excel
用姓名为匹配对象,把现居地址放到户籍地址右侧列
豆包,阿夏
20260820
'''
import pandas as pd
# ========== 修改这里为你的两个文件路径 ==========
path=r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260821园园通小班双地址修改"
file_hukou = path+r"\01 小班户籍地址合并结果.xlsx" # 姓名+户籍地址
file_live = path+r"\02 园园通小班幼儿列表导出文件.xlsx" # 姓名+居住地址
out_file = path+r"\03 小班合并双地址.xlsx"
# =============================================
# 读取两张表
df_hukou = pd.read_excel(file_hukou)
df_live = pd.read_excel(file_live)
# 清洗姓名:去除前后空格,避免空格导致匹配失败
df_hukou["姓名"] = df_hukou["姓名"].astype(str).str.strip()
df_live["姓名"] = df_live["姓名"].astype(str).str.strip()
# 只保留需要的列:姓名、居住地址
df_live_slim = df_live[["姓名", "现居地-详细地址"]]
# 左连接:以户籍表为主表,匹配居住地址
result = pd.merge(
df_hukou,
df_live_slim,
on="姓名",
how="left"
)
# 输出
result.to_excel(out_file, index=False)
print(f"✅完成,输出文件:{out_file}")
print(f"一共 {len(result)} 条记录")
顺利合并,户籍地址已经很完整了,现居地不完整
右侧做一列"市区"
用"&"进行组合
右对齐,补"室"
现在改好了,
(三)把小班幼儿的姓名、拼合的户籍地址、居住地址,组合在一张工作表上,Python模拟人工再园园通上修改。
为了怕园园通卡死,125拆分成5组,每组25人
'''
园园通小班孩子 两个地址补全(省市区)再次写入园园通。(单独做的组合xlsx)
火狐浏览器,必须100%
为防止园园通变慢,30-40人一组。完成后关闭园园通,再次开启
豆包,阿夏
20260820
'''
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, 3)
time.sleep(t)
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260821园园通小班双地址修改\20260819小班幼儿双地址补全.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=51, values_only=True): # 从第二行开始读取姓名
for row in ws.iter_rows(min_row=2, max_row=26, values_only=True): # 做测试第一组人员,防止园园通卡通。 36=杨
# for row in ws.iter_rows(min_row=27, max_row=51, values_only=True): # 做测试第2组人员,防止园园通卡通。36还是杨, 67=汪 要从68开始+35 68刘
# for row in ws.iter_rows(min_row=53, max_row=76, values_only=True): # 第3组
# for row in ws.iter_rows(min_row=77, max_row=101, values_only=True): #第4组
# for row in ws.iter_rows(min_row=106, max_row=126, values_only=True): #第4组
# for row in ws.iter_rows(min_row=21, values_only=True): # 如果出问题,断了,从第X行读取孩子姓名
name = row[0] # 姓名1
Registered_Address = row[4] # 户口地址5
Residential_Address = row[5] # 居住地址6
# print(name,Residential_Address)
# 点击姓名栏,
pyautogui.click(861,376)
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(name)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 搜索
pyautogui.click(758,497)
rand_sleep()
# 编辑
pyautogui.click(1652,671)
time.sleep(3)
# 模拟滚动到底部
pyautogui.click(1652,671)
for _ in range(2):
pyautogui.scroll(-1000)
rand_sleep()
# time.sleep(0.3) # 每滚轮一下间隔0.3秒
# 户籍地址点击三次
for i in range(3):
pyautogui.click(1404,473)
rand_sleep()
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(Registered_Address)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 居住地址点击三次
for i in range(3):
pyautogui.click(1173,771)
rand_sleep()
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(Residential_Address)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 下移到底部
for _ in range(1):
pyautogui.scroll(-1000)
rand_sleep()
# 确认,回到最初的界面
pyautogui.click(1027,857)
time.sleep(6) # 保存时间长一点
# 自动最大化VSCode
win.maximize()
print("VSCode已自动最大化,程序结束")
分五次运行,每次开始前都关闭园园通,再打开,防止卡顿,25人每次大约13分钟。
(四)人工选择"外省市""外省区"
Excel筛选外省户籍名单,Python设置程序,自动打开幼儿的网页名单,默认停顿10秒,让老师根据居住地址,手动选择"外省市""外省区",10秒后自动保存。
我尝试过 三个按钮是否可以输入文字(不要用手选)
1.户口所在地省份,可以文字输入
2.户口所在地市区,不可以文字输入,只能手选
3.户口所在地区县,可以文字输入、
由于外省户口的"市",不能输入,所以我还是采用人工手选方式------Excel筛选外省户籍名单,Python设置程序,自动打开幼儿的网页名单,默认停顿10秒,让老师根据居住地址,手动选择"外省市""外省区",10秒后自动保存。
2-57行和119-126是外省户籍。
先测试119-126
'''
园园通小班孩子 对外省户籍地址进行手动选择"户籍市"户籍"区"
火狐浏览器,必须100%
为防止园园通变慢,30-40人一组。完成后关闭园园通,再次开启
豆包,阿夏
20260820
'''
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, 3)
time.sleep(t)
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260821园园通小班双地址修改\20260819小班幼儿双地址补全.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=51, values_only=True): # 从第二行开始读取姓名
# for row in ws.iter_rows(min_row=2, max_row=57, values_only=True): # 做测试第一组人员,防止园园通卡通。 36=杨
# for row in ws.iter_rows(min_row=27, max_row=51, values_only=True): # 做测试第2组人员,防止园园通卡通。36还是杨, 67=汪 要从68开始+35 68刘
# for row in ws.iter_rows(min_row=53, max_row=76, values_only=True): # 第3组
# for row in ws.iter_rows(min_row=77, max_row=101, values_only=True): #第4组
for row in ws.iter_rows(min_row=119, max_row=126, values_only=True): #第4组
# for row in ws.iter_rows(min_row=21, values_only=True): # 如果出问题,断了,从第X行读取孩子姓名
name = row[0] # 姓名1
# Registered_Address = row[4] # 户口地址5
# Residential_Address = row[5] # 居住地址6
# print(name,Residential_Address)
# 点击姓名栏,
pyautogui.click(861,376)
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(name)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 搜索
pyautogui.click(758,497)
rand_sleep()
# 编辑
pyautogui.click(1652,671)
time.sleep(3)
# 模拟滚动到底部
pyautogui.click(1652,671)
for _ in range(2):
pyautogui.scroll(-1000)
rand_sleep()
# time.sleep(0.3) # 每滚轮一下间隔0.3秒
time.sleep(10)
# # 户籍地址点击三次
# for i in range(3):
# pyautogui.click(1404,473)
# rand_sleep()
# # 1. 复制指定文字到剪贴板
# # print('写入姓名:',name)
# pyperclip.copy(Registered_Address)
# # 2. 模拟Ctrl+V粘贴
# pyautogui.hotkey("ctrl", "v")
# rand_sleep() # 延迟2秒切换窗口
# # 居住地址点击三次
# for i in range(3):
# pyautogui.click(1173,771)
# rand_sleep()
# # 1. 复制指定文字到剪贴板
# # print('写入姓名:',name)
# pyperclip.copy(Residential_Address)
# # 2. 模拟Ctrl+V粘贴
# pyautogui.hotkey("ctrl", "v")
# rand_sleep() # 延迟2秒切换窗口
# 下移到底部
for _ in range(1):
pyautogui.scroll(-1000)
rand_sleep()
# 确认,回到最初的界面
pyautogui.click(1027,857)
time.sleep(6) # 保存时间长一点
# 自动最大化VSCode
win.maximize()
print("VSCode已自动最大化,程序结束")
存在问题:
1、前面两个孩子是外省的,10秒改外省市、外省区的按钮,时间很紧。
2、后面所有孩子都是上海的,它似乎不是按照我筛选后的行数来算,还是按照姓名的字母排序来算,计算最后所有Z字母姓氏的孩子
我把户外地址排序(升序)后,再次保存一下,然后隐藏掉代码,测试打印姓名,这次不再是Z姓氏,而是打乱的外地户籍孩子姓氏
间隔时间15秒
'''
园园通小班孩子 对外省户籍地址进行手动选择"户籍市"户籍"区"
火狐浏览器,必须100%
为防止园园通变慢,30-40人一组。完成后关闭园园通,再次开启
豆包,阿夏
20260820
'''
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, 3)
time.sleep(t)
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260821园园通小班双地址修改\20260819小班幼儿双地址补全.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=51, values_only=True): # 从第二行开始读取姓名
# for row in ws.iter_rows(min_row=2, max_row=57, values_only=True): # 做测试第一组人员,防止园园通卡通。 36=杨
# for row in ws.iter_rows(min_row=27, max_row=51, values_only=True): # 做测试第2组人员,防止园园通卡通。36还是杨, 67=汪 要从68开始+35 68刘
# for row in ws.iter_rows(min_row=53, max_row=76, values_only=True): # 第3组
# for row in ws.iter_rows(min_row=77, max_row=101, values_only=True): #第4组
for row in ws.iter_rows(min_row=119, max_row=126, values_only=True): #第4组
# for row in ws.iter_rows(min_row=21, values_only=True): # 如果出问题,断了,从第X行读取孩子姓名
name = row[0] # 姓名1
Registered_Address = row[4] # 户口地址5
Residential_Address = row[5] # 居住地址6
print(name,Residential_Address)
# 点击姓名栏,
pyautogui.click(861,376)
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(name)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 搜索
pyautogui.click(758,497)
rand_sleep()
# 编辑
pyautogui.click(1652,671)
time.sleep(3)
# 模拟滚动到底部
pyautogui.click(1652,671)
for _ in range(2):
pyautogui.scroll(-1000)
rand_sleep()
# time.sleep(0.3) # 每滚轮一下间隔0.3秒
time.sleep(15)
# # 户籍地址点击三次
# for i in range(3):
# pyautogui.click(1404,473)
# rand_sleep()
# # 1. 复制指定文字到剪贴板
# # print('写入姓名:',name)
# pyperclip.copy(Registered_Address)
# # 2. 模拟Ctrl+V粘贴
# pyautogui.hotkey("ctrl", "v")
# rand_sleep() # 延迟2秒切换窗口
# # 居住地址点击三次
# for i in range(3):
# pyautogui.click(1173,771)
# rand_sleep()
# # 1. 复制指定文字到剪贴板
# # print('写入姓名:',name)
# pyperclip.copy(Residential_Address)
# # 2. 模拟Ctrl+V粘贴
# pyautogui.hotkey("ctrl", "v")
# rand_sleep() # 延迟2秒切换窗口
# 下移到底部
for _ in range(1):
pyautogui.scroll(-1000)
rand_sleep()
# 确认,回到最初的界面
pyautogui.click(1027,857)
time.sleep(6) # 保存时间长一点
# 自动最大化VSCode
win.maximize()
print("VSCode已自动最大化,程序结束")
15秒操作正好,但是外省户籍的位置有点遮挡,
新代码做2-57
'''
园园通小班孩子 对外省户籍地址进行 人工手动选择"户籍市"户籍"区",间隔15秒
火狐浏览器,必须100%
为防止园园通变慢,30-40人一组。完成后关闭园园通,再次开启
豆包,阿夏
20260820
'''
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, 3)
time.sleep(t)
file_path = r"C:\Users\mhjg2\Desktop\20260805园园通小班分班\20260821园园通小班双地址修改\20260819小班幼儿双地址补全.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=119, max_row=119,values_only=True): # 从第二行开始读取姓名
for row in ws.iter_rows(min_row=2, max_row=57, values_only=True): # 做测试第一组人员,防止园园通卡通。 36=杨
# for row in ws.iter_rows(min_row=27, max_row=51, values_only=True): # 做测试第2组人员,防止园园通卡通。36还是杨, 67=汪 要从68开始+35 68刘
# for row in ws.iter_rows(min_row=53, max_row=76, values_only=True): # 第3组
# for row in ws.iter_rows(min_row=77, max_row=101, values_only=True): #第4组
# for row in ws.iter_rows(min_row=119, max_row=126, values_only=True): #第4组
# for row in ws.iter_rows(min_row=21, values_only=True): # 如果出问题,断了,从第X行读取孩子姓名
name = row[0] # 姓名1
Registered_Address = row[4] # 户口地址5
Residential_Address = row[5] # 居住地址6
print(name,Residential_Address)
# 点击姓名栏,
pyautogui.click(861,376)
# 1. 复制指定文字到剪贴板
# print('写入姓名:',name)
pyperclip.copy(name)
# 2. 模拟Ctrl+V粘贴
pyautogui.hotkey("ctrl", "v")
rand_sleep() # 延迟2秒切换窗口
# 搜索
pyautogui.click(758,497)
rand_sleep()
# 编辑
pyautogui.click(1652,671)
time.sleep(3)
time.sleep(3)
# 模拟滚动到底部
pyautogui.click(1652,671)
for _ in range(2):
pyautogui.scroll(-500)
rand_sleep()
# time.sleep(0.3) # 每滚轮一下间隔0.3秒
time.sleep(15)
# # 户籍地址点击三次
# for i in range(3):
# pyautogui.click(1404,473)
# rand_sleep()
# # 1. 复制指定文字到剪贴板
# # print('写入姓名:',name)
# pyperclip.copy(Registered_Address)
# # 2. 模拟Ctrl+V粘贴
# pyautogui.hotkey("ctrl", "v")
# rand_sleep() # 延迟2秒切换窗口
# # 居住地址点击三次
# for i in range(3):
# pyautogui.click(1173,771)
# rand_sleep()
# # 1. 复制指定文字到剪贴板
# # print('写入姓名:',name)
# pyperclip.copy(Residential_Address)
# # 2. 模拟Ctrl+V粘贴
# pyautogui.hotkey("ctrl", "v")
# rand_sleep() # 延迟2秒切换窗口
# 下移到底部
for _ in range(1):
pyautogui.scroll(-1000)
rand_sleep()
# 确认,回到最初的界面
pyautogui.click(1027,857)
time.sleep(6) # 保存时间长一点
# 自动最大化VSCode
win.maximize()
print("VSCode已自动最大化,程序结束")
中间操作时,发现某些省市的市选不出来,就知道这个"省""市"中间,还有一个"市",所以暂停程序,到豆包"搜索"中间的市,所以时间很长。
中国真的地大物博,幅员辽阔,省、市、下面有好多的"区""县""乡"!!!
感悟:
1.设计流程:
用Python批量输入姓名,点击搜索、编辑,下滑页面到户籍地址为止,然后我再观察户籍地址,手选"区"里面的相应区,再手选"区"里面的相应区。选完就不用管了,等15秒时间耗尽,Python点击保存。继续循环下一个名字。
2.节省人工
虽然用时也很长,但是Python完成大部分页面按钮操作,我只需要化5-10秒选择区域,剩下都是它来完成,真的省了很多人工,不会出现反复复制、反复黏贴带来的焦躁感。
3.数据精准
在Python代码的协助下,我终于把所有园园通里面的户籍地址的"省""市""区"修改正确了。过去如果遇到这么大的工作量,我会自动忽略,不去修改里面的"市""区"。但是现在有Python助力,就可能让幼儿的信息数据更准确,而人工清洗后的地址,格式规范统一,便于后续"保健"统一使用。
验证:重新把小班数据下载,检查双地址
还是有错误的
在园园通里搜搜名字,人工修改
再次下载打包文件,再次核查
上海居住地都正确了(但是个别家长写到"号",没有写"室")
总体来说,通过反复比对,逐步将小班的户籍地址、居住地址,完善正确。