由于SAP系统自身原因,或者公司内部ABAP代码的算法效率不高,我们经常遇到,手工执行某个事务代码下载某个报表会非常耗时,小爬曾见过公司某个自开发的报表,单家公司的数据下载超过半小时。如果我们刚好接到一个自动化需求:批量下载N个公司的某些报表数据,即使我们用python脚本实现了该场景的自动化,效率依然不高。

  或许我们可以尝试python的多线程技术来加速。这应该是个好主意,现在小爬就带着大家往多线程这个方向思考。

  SAP GUI的会话数量一般都有限制,各个公司的SAP策略或有不同,在小爬所在的公司,SAP GUI客户端允许的会话数不超过6,我们不妨用多个会话分别去下载数据。小爬遇到的场景是:有N家公司,分别进入4个事务代码下载四张不同的表,这四张表的导出速度各有不同,有的较快,有的极慢。

方案一:我们启用四个sap会话,分别下载这四张表,每次参数中传入不同的公司代码;

方案二:我们开启最大SAP会话数6,每个会话都执行一些公司代码,也都会下载到这四张表。

  仔细思考后不难发现,方案二可以将下载速度最大化。方案一中各个会话对应的报表下载速度各不相同,最终速度受最慢的那个影响,而且它只能根据四张报表来启用四个会话线程;而方案一,则可以同时开启六个SAP会话线程,且每个会话下都会下载这四张表,无形中,避免了”一个会话在苦战,其它会话全围观“的尴尬局面。

  具体到代码层面,我们需要批量创建多个sap会话,新建一个全局的任务队列companyQ,每个sap会话独自不停去队列中取任务(下载需要的参数),驱动各自负责的SAP会话来完成数据的下载,当队列中所有任务都完成了,意味着线程结束。等以上思路都琢磨明白了,代码该怎么写就不再是一个问题了。

第一步:定义连接sap的方法,并自动开启N个session会话

第二部:定义下载SAP数据的方法

第三步:开启多个线程,分别调用同一个方法,传入不同session的index作为参数,实现对多个会话的自动化控制

def connect_SAP(maxSessionNum):
'''连接SAP,并创建maxSessionNum个session会话,返回session列表(含session索引)'''
SapGuiAuto = win32com.client.GetObject("SAPGUI")
application = SapGuiAuto.GetScriptingEngine
connection = application.Children(0)
indexSessions=[]
session=connection.Children(0)
cnt=connection.Children.Count
if cnt<maxSessionNum:
for _ in range(maxSessionNum-cnt):
session.Createsession()
sleep(0.5)
sleep(2)
for index,session in enumerate(connection.Children):
indexSessions.append([index,session])
SapGuiAuto=None
application=None
connection=None
session=None
return indexSessions

def exportSapData(sessionIndex):
'''给定公司代码,期间,依次导出应收社保、公积金,应付社保、公积金报表数据'''
pythoncom.CoInitialize()
SapGuiAuto = win32com.client.GetObject("SAPGUI")
application = SapGuiAuto.GetScriptingEngine
connection = application.Children(0)
session=connection.Children(sessionIndex) '''输入zhr054,导出HR社保往来挂账应付公积金明细表'''
session.findById("wnd[0]").iconify()
unfinishedNum=companyQ.unfinished_tasks
while True:
lk.acquire()
if not companyQ.empty():
companyCode=companyQ.get(block=False)
else:
lk.release()
break
lk.release()
downloadFunc(companyCode,reportPeriod)

  下面的代码便演示了如何借助python多线程技术,针对每个线程,传入的参数就是session的索引号(0-6),最终把他们分别启动起来~

connect_SAP(maxSessionNum=5)
sleep(3)
threads = []
for i in range(6):
    threads.append(threading.Thread(target=exportSapData,args=(i,)))
for companyCode in companies:
    companyQ.put(companyCode)
for t in threads:
    t.setDaemon(True)
    t.start()
for t in threads:
    t.join()
 
print ("all over %s" %ctime())
endtime = datetime.datetime.now()
secs = (endtime - starttime).seconds
minutes = secs // 60
second = secs % 60  
timeStr = str(minutes) + '分钟' + str(second) + "秒"
root=tk.Tk()
root.withdraw()
tkinter.messagebox.showinfo("信息",f"已完成所有数据下载,运行时间为:{timeStr}")

  以上,就是小爬利用python多线程来驱动sap多个会话进行特定自动化操作的主要过程。基于这一波操作,整个下载效率可以提升4-6倍。那一刻,仿佛有6个自动化机器人在同时帮小爬分担枯燥的数据下载工作,幸福感瞬间拉满!!!

  有任何疑问,欢迎评论区积极留言,同时也欢迎扫码关注我的公众号,获取更多爬虫、数据分析的知识!

SAP下载报表速度慢?为啥你不试试python多线程的更多相关文章

  1. 启动运行下载gradle速度太慢,手动添加

    启动运行下载gradle速度太慢,并且容易卡死(感谢群友ˋ狠ㄨ得意提供支持)---国内网络访问地址 我们经常运行项目的时候会需要进行下载gradle,不过由于网络或者和谐的问题经常下载需要花很长时间或 ...

  2. Python3 解决windows里PIP下载安装速度慢

    直接保存为xxx.py运行即可 自动在用户文件夹创建pip文件夹,并创建配置文件:pip.ini 从此告别pip install XXXX 下载模块速度超级慢的问题! # -*- coding: ut ...

  3. python多线程爬虫+批量下载斗图啦图片项目(关注、持续更新)

    python多线程爬虫项目() 爬取目标:斗图啦(起始url:http://www.doutula.com/photo/list/?page=1) 爬取内容:斗图啦全网图片 使用工具:requests ...

  4. python多线程批量下载远程图片

    python多线程使用场景:多线程采集, 以及性能测试等 . 数据库驱动类-简单封装下 mysqlDriver.py #!/usr/bin/python3 #-*- coding: utf-8 -*- ...

  5. 以下三种下载方式有什么不同?如何用python模拟下载器下载?

    问题始于一个链接https://i1.pixiv.net/img-zip-...这个链接在浏览器打开,会直接下载一个不完整的zip文件 但是,使用下载器下载却是完整文件 而当我尝试使用python下载 ...

  6. SAP 快速报表

    快速报表,这个名字不知道是不是第一个用,不过以这种方式做的报表,速度确实挺快的,应该比QUERY快,还简单 T-CODE:SQVI 进入界面后,输入一个报表名称,点击新建,这时候可以选择,单表查询,链 ...

  7. iOS开发下载文件速度计算

    当我们写下载界面的时候,需要向用户展示每秒下载多少KB,这个时候就需要计算速度.如下: 我用的是AFNetworking来做下载的,我们拿AFHTTPRequestOperation来举列,AFHTT ...

  8. GitHub克隆下载代码速度慢解决办法

    这几天克隆下载GitHub代码奇慢无比,网上搜索了一下解决方案有些不太完整,自己试验出了比较完整的解决方式: 1.在hosts文件里追加以下内容(IP需要替换掉),以下几个域名一个都不要少,有些文章只 ...

  9. WPF SAP水晶报表例子和打包Setup

    <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=" ...

随机推荐

  1. 【LeetCode】119. 杨辉三角 II Pascal‘s Triangle II(Python & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题思路 方法一: 空间复杂度 O ( k ∗ ( k + 1 ...

  2. 【LeetCode】380. Insert Delete GetRandom O(1) 解题报告(Python)

    [LeetCode]380. Insert Delete GetRandom O(1) 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxu ...

  3. Lotus and Horticulture

    Lotus and Horticulture Accepts: 91 Submissions: 641 Time Limit: 4000/2000 MS (Java/Others) Memory Li ...

  4. 【LeetCode】809. Expressive Words 解题报告(Python)

    [LeetCode]809. Expressive Words 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...

  5. computer(hdu2196)

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  6. 深度探索 OpenStack Neutron:BGP(1) 【转载】

    3.4 BGP 原文地址:http://mp.weixin.qq.com/s?src=3&timestamp=1500043305&ver=1&signature=XwiIVV ...

  7. Gradient-based Hyperparameter Optimization through Reversible Learning

    目录 概 主要内容 算法 finite precision arithmic 实验 Maclaurin D, Duvenaud D, Adams R P, et al. Gradient-based ...

  8. TensorFlow.NET机器学习入门【7】采用卷积神经网络(CNN)处理Fashion-MNIST

    本文将介绍如何采用卷积神经网络(CNN)来处理Fashion-MNIST数据集. 程序流程如下: 1.准备样本数据 2.构建卷积神经网络模型 3.网络学习(训练) 4.消费.测试 除了网络模型的构建, ...

  9. Salesforce LWC学习(三十八) lwc下如何更新超过1万的数据

    背景: 今天项目组小伙伴问了一个问题,如果更新数据超过1万条的情况下,有什么好的方式来实现呢?我们都知道一个transaction只能做10000条DML数据操作,那客户的操作的数据就是超过10000 ...

  10. 知识增强的预训练语言模型系列之ERNIE:如何为预训练语言模型注入知识

    NLP论文解读 |杨健 论文标题: ERNIE:Enhanced Language Representation with Informative Entities 收录会议:ACL 论文链接: ht ...