目录
简单介绍
RPA全称Robotic Process Automation,即机器流程自动化,是2017年才开始兴起的技术,现在在财务领域,税务等多个领域都有比较广泛的应用,相信AI大家并不陌生,人工智能嘛,如果把AI比喻为人的大脑,那么RPA更像是人类的手脚,AI倾向于做发出指令,判断等类似人类大脑的行为,而RPA则是根据指令去执行相应的流程,一些枯燥的,重复的,有规律可循的工作可以通过RPA来解决。
需求分析
最近有个当老师的朋友遇到了一个难题,学校对于老师有比较严格的考核制度,每个老师都有自己的个人空间,每天的访问量必须达到100才行,要知道,一个教育的官网去哪里搞到100的访问量,没办法,只能拿现有的学生或老师的账号互相一个个手工访问,费时费力。最后找到了我,开始我听到这个需求的时候首先想到的是利用爬虫解决,具体流程应该是这样,访问个人空间 》 在空间进行登录》登录成功》退出,然后换账号循环登录即可,乍一想是比较简单,然后就去到了对应的网站。
爬虫 OR rpa
当我去到网站用账号去登录的时候瞬间感到后背一阵刺痛,这是network请求,如下:
没错,带着一大串的cookie,然后请求参数还有个callback,应该是使用了jsoup跨域,这都不是重点,重点是账号密码给加密了,这就比较恶心,虽然你知道加密方法一般是写在某个js当中,但是实在不想耗费精力去找,而且除了加密的账号和密码还有其他乱七八糟的参数需要传递,就算有幸找到了加密的方法,后面估计也有一大堆的坑在等着你。本来这个当老师的朋友是想用爬虫解决的,最后束手无策才找到我,这我才明白其中的原因,虽然在爬虫和反爬虫的战争当中最终的结果一定是爬虫获胜,但是这个东西不值得去耗费太大的精力,迅速解决问题才是王道,而且后来我了解到访问空间的时候需要呆上几秒钟的时间才算一个访问量,而且这个网站并不是那么稳定,访问次数过多还会让你有一小段时间无法访问,这样的话使用爬虫在速度上也不会有太大的优势,虽然可以开多个线程去爬,最后想想还是算了。。。
最终实现
最终经过一番思想斗争,决定采用RPA来解决此问题,这里我用的是 艺赛旗 的设计器,界面以及我设计的流程如下:
设计器会根据设计流程生成相应的python代码,艺赛旗有一套自己的python包,里面集成了各种自己独有的库,使用它的python库直接运行下面的python脚本也是可以的,这样就可以脱离设计器了。看一下生成的python代码,其实很少,如下:
# coding=utf-8
import time
import pdb
from ubpa.ilog import ILog
from ubpa.base_img import *
import getopt
from sys import argv
import sys
from ubpa.itools import rpa_import
GlobalFun = rpa_import.import_global_fun(__file__)
import ubpa.iautomation as iautomation
import ubpa.ibox as ibox
import ubpa.iexcel as iexcel
import ubpa.iie as iie
import ubpa.ikeyboard as ikeyboard
class refreshTeacher:
def __init__(self,**kwargs):
self.__logger = ILog(__file__)
self.path = set_img_res_path(__file__)
self.robot_no = ''
self.proc_no = ''
self.job_no = ''
if('robot_no' in kwargs.keys()):
self.robot_no = kwargs['robot_no']
if('proc_no' in kwargs.keys()):
self.proc_no = kwargs['proc_no']
if('job_no' in kwargs.keys()):
self.job_no = kwargs['job_no']
def Main(self):
strMsg=''
errorMsg=None
noList=[]
currentTitle=None
accountNo=None
accountLength=None
urlLength=None
url=None
#工作表行数获取
self.__logger.debug('Flow:Main,StepNodeTag:2113420630986,Note:')
urlLength = iexcel.get_rows_count(path='D:/accountMsg/accountMsg.xls')
#工作表行数获取
self.__logger.debug('Flow:Main,StepNodeTag:2113460296793,Note:')
accountLength = iexcel.get_rows_count(path='D:/accountMsg/accountMsg.xls',sheet=1)
# For循环
self.__logger.debug('Flow:Main,StepNodeTag:21134801289101,Note:')
for i in range(0,urlLength):
#单元格读取
self.__logger.debug('Flow:Main,StepNodeTag:2113400171676,Note:')
url = iexcel.read_cell(path='D:/accountMsg/accountMsg.xls',cell='A'+str(i+1))
#网站
self.__logger.debug('Flow:Main,StepNodeTag:2023521550939,Note:')
iie.open_url(url=str(url))
time.sleep(1)
# 自定义函数
self.__logger.debug('Flow:Main,StepNodeTag:211951577903,Note:')
currentTitle = GlobalFun.getTitle(str(url))
# For循环
self.__logger.debug('Flow:Main,StepNodeTag:2023490080930,Note:')
for j in range(0,accountLength):
#单元格读取
self.__logger.debug('Flow:Main,StepNodeTag:21140726533132,Note:')
accountNo = iexcel.read_cell(path='D:/accountMsg/accountMsg.xls',sheet=1,cell='A'+str(j+1))
# Try异常
self.__logger.debug('Flow:Main,StepNodeTag:21145243060147,Note:')
try:
# 鼠标点击
self.__logger.debug('Flow:Main,StepNodeTag:202316387715,Note:')
time.sleep(1.5)
iie.do_click_pos(win_title=currentTitle,url=str(url),selector=r'.loginBefore fr > LI:nth-of-type(1) > A:nth-of-type(1)',button=r'left',curson=r'center',times=1,run_mode=r'ctrl',waitfor=100,scroll_view='no')
time.sleep(1)
# 鼠标点击
self.__logger.debug('Flow:Main,StepNodeTag:2023274364415,Note:')
iie.do_click_pos(win_title=currentTitle,url=str(url),selector=r'#logoCaseTab',button=r'left',curson=r'center',times=1,run_mode=r'ctrl',waitfor=1000,scroll_view='no')
time.sleep(1.5)
# 设置文本
self.__logger.debug('Flow:Main,StepNodeTag:202319213487,Note:')
iie.set_text(url=str(url),selector=r'INPUT[name=account]',text=str(accountNo).split('.')[0],waitfor=10)
# 设置文本
self.__logger.debug('Flow:Main,StepNodeTag:202321033999,Note:')
iie.set_text(url=str(url),selector=r'INPUT[name=pwd]',text=r'密码',waitfor=10)
# 鼠标点击
self.__logger.debug('Flow:Main,StepNodeTag:2023223947811,Note:')
iie.do_click_pos(win_title=currentTitle,url=str(url),selector=r'INPUT[class=login_btn UserLoginBtn-1 m_btn submit][type=button]',button=r'left',curson=r'center',times=1,run_mode=r'ctrl',waitfor=10,scroll_view='no')
time.sleep(8.5)
# 鼠标点击
self.__logger.debug('Flow:Main,StepNodeTag:2023262159313,Note:')
iie.do_click_pos(win_title=currentTitle,url=str(url),selector=r'A[class=outSpace][href=http://www.fjedu.cn/index.php?r=portal/user/logout]',button=r'left',curson=r'center',times=1,run_mode=r'ctrl',waitfor=7,scroll_view='no')
time.sleep(2)
# 设置文本
self.__logger.debug('Flow:Main,StepNodeTag:2023540170942,Note:')
iautomation.WinSearchDepth=2
selectorJson = {"selector":[{"ControlType":"编辑","ControlTypeID":"0xC354","Index":"1"},{"ControlType":"窗格","ControlTypeID":"0xC371","Index":"2"},{"ControlType":"窗格","ControlTypeID":"0xC371","Index":"1"},{"ControlType":"窗格","ControlTypeID":"0xC371","Index":"2"}]}
iautomation.set_text(win_class=r'IEFrame',win_name=r'福建省教育资源公共服务平台-以科技助力教育,让每一个孩子快乐学习、全面成长! - Internet Explorer',selector=selectorJson,text=str(url),waitfor=20)
# 键盘输入
self.__logger.debug('Flow:Main,StepNodeTag:2023570847844,Note:')
ikeyboard.key_send_cs(win_title=r'福建省教育资源公共服务平台-以科技助力教育,让每一个孩子快乐学习、全面成长! - Internet Explorer',text='{ENTER}',waitfor=10)
time.sleep(3.5)
except Exception as e:
# 代码块
self.__logger.debug('Flow:Main,StepNodeTag:2120205931934,Note:')
noList.append(str(url)+' 这个网址的 '+str(accountNo).split('.')[0]+' 号码出现未知错误,修复出错的号码,重新跑一遍即可')
# 热键输入
self.__logger.debug('Flow:Main,StepNodeTag:2213423454679,Note:')
ikeyboard.key_send_cs(text='^{F4}',waitfor=10)
time.sleep(2)
#消息框
self.__logger.debug('Flow:Main,StepNodeTag:21145841720160,Note:')
ibox.msg_box(msg=str(url)+' 从'+str(accountNo).split('.')[0]+' 号码开始出现未知错误,忽略,开始下个号码',timeout=1.5)
time.sleep(2.8)
#网站
self.__logger.debug('Flow:Main,StepNodeTag:2213472398682,Note:')
iie.open_url(url=str(url))
time.sleep(2)
# Continue继续
self.__logger.debug('Flow:Main,StepNodeTag:2213480816984,Note:')
continue
finally:
pass
# 热键输入
self.__logger.debug('Flow:Main,StepNodeTag:2213481637185,Note:')
ikeyboard.key_send_cs(text='^{F4}',waitfor=10)
time.sleep(2)
# IF分支
self.__logger.debug('Flow:Main,StepNodeTag:2120215504237,Note:')
if len(noList)==0:
pass
else:
# For循环
self.__logger.debug('Flow:Main,StepNodeTag:2120293417148,Note:')
for msg in noList:
# 代码块
self.__logger.debug('Flow:Main,StepNodeTag:2120295258450,Note:')
strMsg += str(msg)+'; '
#消息框
self.__logger.debug('Flow:Main,StepNodeTag:2120301700952,Note:')
ibox.msg_box(msg=strMsg)
#消息框
self.__logger.debug('Flow:Main,StepNodeTag:21145604215155,Note:')
ibox.msg_box(msg='所有空间刷取完毕')
if __name__ == '__main__':
robot_no = ''
proc_no = ''
job_no = ''
try:
argv = sys.argv[1:]
opts, args = getopt.getopt(argv,"hr:p:j:",["robot = ","proc = ","job = "])
except getopt.GetoptError:
print ('robot.py -r <robot> -p <proc> -j <job>')
for opt, arg in opts:
if opt == '-h':
print ('robot.py -r <robot> -p <proc> -j <job>')
elif opt in ("-r", "--robot"):
robot_no = arg
elif opt in ("-p", "--proc"):
proc_no = arg
elif opt in ("-j", "--job"):
job_no = arg
pro = refreshTeacher(robot_no=robot_no,proc_no=proc_no,job_no=job_no)
pro.Main()
大体思路是这样的:把网络空间的地址信息填入excel的第一个sheet页,账号信息填到第二个sheet页,然后读取网址循环访问网站登录账号实现访问量刷取,其中对于网址打开失败等情况做了异常处理,会循环打开网站,直到打开为止。看一下excel的格式
这里就放了两个测试账号,密码就不公开了。这样一来,花了半个小时来进行流程的设计,然后又花了半个小时的时间进行相应的调试,后来帮朋友远程安装部署,前后花了大概两个小时的时间,在开发效率上实在比爬虫高出许多,最后我把启动程序做成了一个bat放在了桌面上,直接双击运行即可,脱离了设计器运行的不便,bat代码如下,很简单:
D:\RPA\plugin\Com.Isearch.Func.Python\python D:\RPA\plugin\Com.Isearch.Func.Python\Test.py
pause
其实就是用python运行py文件。
总体的运行效果就是打开网站登录,间隔几秒退出,然后再次进入空间登录,间隔几秒退出。。。等到本轮所有账号登录完毕,打开下一个网址登录,间隔几秒退出,一直循环,直到结束为止,部分运行效果如下所示:
这样利用RPA就比较容易得解决了访问量的问题,相比爬虫来说省了不少功夫,其实不只是在网站方面,rpa在其他领域也有着广泛的应用,这也只是冰山一角罢了,喜欢的朋友可以自行了解,这东西易学难精,但是一旦精通,还是能够帮助解决很多问题的!
好了,今天就到这里,码字不易,喜欢的朋友点赞关注,转发还望注明出处,谢谢!代码生成器本周或下周更新!您的支持是我最大的动力!