使用Python从Outlook提取员工信息突然变慢的技术求助
Outlook通讯组成员提取速度骤降问题排查与优化
我之前用Python的pywin32库从指定Outlook通讯组列表提取成员的姓名、邮箱、职位等信息,100-200个成员仅需1-2分钟。但更换公司笔记本后,相同任务耗时长达1小时,网上未找到相关解决方案,求指导。
原代码示例
import win32com.client import pandas as pd import progressbar as pb outApp = win32com.client.gencache.EnsureDispatch('Outlook.Application').GetNamespace("MAPI") entries = outApp.AddressLists dist_lists = entries['All Distribution Lists'] outlookdf=pd.DataFrame(columns=['User Name','Email','Job Level','Location','Department','DL Name']) dl_names_list = ["<insert name of distribution list here>"] print("Distribution Lists being extracted are: ") for i in dl_names_list: print(str(i)) print("----------------------------") #########GET DL Names from list and put it in a dataframe for i in dl_names_list: print("Distribution List now being extracted: ") print(str(i)) #initialize widgets widgets = ['Remaining Time: ', pb.Percentage(), ' ', pb.Bar(marker=pb.RotatingMarker()), ' ', pb.ETA()] #initialize timer timer = pb.ProgressBar(widgets=widgets, maxval=len(dist_lists.AddressEntries.Item(str(i)).GetExchangeDistributionList().Members)).start() ind = 0 m_list_1 = [] m_list_2 = [] m_list_3 = [] m_list_4 = [] m_list_5 = [] for m in dist_lists.AddressEntries.Item(str(i)).GetExchangeDistributionList().Members: user=m.GetExchangeUser() try: if len(user.Name) > 0 and (user.Name.find(', ') != -1): value1 = user.Name m_list_1.append(value1) value2 = user.PrimarySmtpAddress m_list_2.append(value2) value3 = user.JobTitle m_list_3.append(value3) value4 = user.OfficeLocation m_list_4.append(value4) value5 = user.Department m_list_5.append(value5) timer.update(ind) ind = ind + 1 except: continue timer.finish() print("---------------------------------------------------") df_m = pd.DataFrame(pd.DataFrame( {'User Name': m_list_1, 'Email': m_list_2, 'Job Level': m_list_3, 'Location': m_list_4, 'Department': m_list_5 })) df_m["DL Name"] = str(dist_lists.AddressEntries.Item(str(i)).GetExchangeDistributionList().Name) outlookdf = pd.concat([outlookdf,df_m]) outlookdf = outlookdf.drop_duplicates() outlookdf = outlookdf.reset_index(drop = True)
针对性优化建议
缓存重复调用的COM对象:原代码多次重复调用
dist_lists.AddressEntries.Item(str(i)).GetExchangeDistributionList(),每次都会触发Outlook接口交互,是核心耗时点。提前缓存对象可大幅减少交互次数:# 循环内提前缓存通讯组和成员对象 dl = dist_lists.AddressEntries.Item(str(i)).GetExchangeDistributionList() members = dl.Members timer = pb.ProgressBar(widgets=widgets, maxval=len(members)).start()简化DataFrame构建逻辑:用字典列表直接构建DataFrame,减少中间列表的创建与维护开销,同时避免重复拼接DataFrame:
member_data = [] for m in members: user = m.GetExchangeUser() try: if user.Name and ', ' in user.Name: member_data.append({ 'User Name': user.Name, 'Email': user.PrimarySmtpAddress, 'Job Level': user.JobTitle, 'Location': user.OfficeLocation, 'Department': user.Department, 'DL Name': dl.Name }) ind += 1 timer.update(ind) except: continue df_m = pd.DataFrame(member_data)调整Outlook运行模式:新笔记本可能开启了Outlook缓存模式,同步大量本地数据导致接口响应延迟。可切换至在线模式测试:打开Outlook→文件→账户设置→账户设置→双击Exchange账户→取消勾选“使用缓存Exchange模式”。
检查版本兼容性:确认新笔记本的pywin32版本、Outlook版本与旧电脑是否一致,尝试更新pywin32至最新稳定版,或回退到旧电脑的匹配版本。
优化进度条更新逻辑:将
timer.update(ind)移至try块外,避免条件判断带来的额外开销,确保每次循环仅执行一次进度更新。
内容的提问来源于stack exchange,提问作者Samrat
相关产品推荐
相关产品推荐

