python开发rpa_几步教你用 Python 制作一个 RPA 机器人!
原标题:几步教你用 Python 制作一个 RPA 机器人!
作者 | 阿文
出品 | CSDN(ID:CSDNnews)
头图 | CSDN下载自东方IC
繁琐且重复的工作
在我们日常的工作中,有很多事情是重复且繁琐的,组织内部不同的部门开发出来的系统相互之间并没有过多的依赖关系,于是使用系统的人在利用现有系统去解决问题,经常需要跨越多个不同部门所提供的平台去进行操作,举个例子,在我们的日常工作中会依赖工单系统、用户信息查询系统、审核系统以及内部管理平台。这四个平台都是有不同的部门维护的,相互之间数据不互通。
有时候用户提交了一些审核性质的工单,其中包含 20 几张图片,人工审核下,需要去打开这 20 几张图片获取到指定的信息,然后去上述几个平台去做对应的操作。比如查询、提交等等。这样一来一回一个问题的解决时常可能就需要 1 个小时以上。
那么我们能不能通过机器去自动完成这些固定流程且繁琐的工作呢?答案是肯定的。现阶段,我们可以通过引入 RPA 来实现整个流程的打通。
什么是 RPA
RPA 是机器人流程自动化的简称,听起来很高大上的名字,实际上本质就是自动化,让机器帮人去做一些流程固定的事情,机器可以 7* 24小时不停转的完成工作。但是人最多只能 996,毕竟还是要睡觉的,不能剥削的太狠。
RPA 工具选型
RPA 其实出现的时间不短,但是在国内兴起也就最近几年的事情,成熟的产品并不多,例如阿里云的RPA、国外的uiPath 等等,但是这些工具对于平台依赖性较大,他们只能部署在Windows 操作系统上,而我们希望部署在Linux 服务器上,在命令行模式下运行,这样可以节省资源。
基于此,我们决定通过 Python 来实现自动化,由于我们所需要对接的系统大部分都不会给我们提供现成的 API 接口,我们一开始通过 requests 来模拟登录获取coookies 进行请求,但是这个过程中发现很多页面都是异步加载数据,而 requests 是同步的,无法获取数据,且内部系统做了非常严格的认证鉴权,仅仅靠 requests、Beautiful Soup 等是搞不定这些鉴权的。因此我们需要一些工具来实现模拟浏览器请求爬取数据,对比了目前比较流行的几款开源的自动化工具:
Selenium:老牌自动化测试工具,优点是支持大部分主流浏览器,它提供了功能丰富的API接口,且支持浏览器无头模式,但是缺点也很明显,比如速度太慢、对版本配置要求严苛,最麻烦是经常要更新对应的驱动,每次浏览器升级都需要去重新安装 Chromedriver。
Puppeteer Puppeteer:是一个 Node 库,它提供了高级 API 来通过 DevTools 协议控制 Chrome 或 Chromium,简单理解成我们日常使用的 Chrome 的无界面版本,可以使用 js 接口进行进行操控。意味凡是 Chrome 浏览器能干的事情,Puppeteer 都能出色的完成。
RPAfor Python:这个是我们最开始使用的一款 RPA 工具,它可以很好的满足我们的需求,且操作也比较简单, 通过 Xpath 定位元素就可以对 DOM 进行操作,但是其与 Selenium 有着相同的缺点即速度慢,且不支持浏览器无头模式运行,也就是说它需要一个桌面环境,对资源消耗较大,尤其是 Chromium 这种吃内存较大的程序。而我们希望将其部署到 Linux 服务器上去,所以 Rap for Python 也就无法满足需求了。
经过对比,最终我们选择了 Puppeteer 的 Python 版本 Pyppeteer 来作为 RPA 工具
Pyppeteer 是什么
Puppeteer(中文翻译”木偶”) 是 Google Chrome 团队官方的无界面(Headless)Chrome 工具,它是一个 Node库,提供了一个高级的 API 来控制 DevTools协议上的无头版 Chrome 。也可以配置为使用完整(非无头)的 Chrome。它非常适合前端开发者进行自动化测试,而我们除了使用这个自动化工具,还有一些其他功能是基于 Python 来开发的,比如使用pandas 处理表格,做数据分析,所以我们选择了一个社区维护的 Pyppeteer ,他的功能几乎和 Puppeteer 一样,所以即使是去看 Puppeteer 的文档也没多大问题。
puppeteer 可以做很多事情,简单来说你可以在浏览器中手动完成的大部分事情都可以使用Puppeteer完成!例如:
生成页面的截图和PDF。
抓取SPA并生成预先呈现的内容(即“SSR”)。
从网站抓取你需要的内容。
自动表单提交,UI测试,键盘输入等
创建一个最新的自动化测试环境。使用最新的Java和浏览器功能,直接在最新版本的Chrome中运行测试。
捕获您的网站的时间线跟踪,以帮助诊断性能问题。
开始使用 Pyppeteer
1.无头模式配置
在打开浏览器的时候,我们需要设定一些参数,如果你需要它跑在容器里面或纯字符模式的 Linux 中,则 headless 参数必须设置为 true,同时 args 中的参数也要加上,它主要是关闭Chrome 一些没有必要的功能,例如扩展、flash、音频和gpu等,以达到节省资源的目的,executablePath 可以指定浏览器的目录,默认 Pyppeteer 会自动去执行 Pyppeteer-install 来下载 Chromium,在国内下载极其慢,建议提前安装好 Chromium。
browser = await launch(
{ 'executablePath': self.config[ "Chromium_path_linux"], #设置浏览器路径
'headless': True,
"autoClose": True,
"args": [
'--disable-extensions',
'--hide-scrollbars',
'--disable-bundled-ppapi-flash',
'--mute-audio',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-gpu',
],
'dumpio': True
})
参数含义
2.异步编码
由于 Pyppeteer 是异步的因此在 Python 中 需要使用async def 来增加方法。
3.注入cookie
在一些场合,我们需要与 requests 进行结合,因为整体上 requets 的效率和实现相对比较容易些,可以在必要的时候调用 Pyppeteer 唤起浏览器,因此可以通过设置cookie 来让 Pyppeteer 登录某个页面
awaitpage.setExtraHTTPHeaders(cookies)
4.阻塞
在一些场景,我们需要进行阻塞,比如说页面加载中,但是程序执行的很快,可能还没加载完就执行其他语句了,这样就拿不到想要的数据,这个时候可以使用page.waitFor 让页面进行等待,不要去使用 time.sleep
awaitpage.waitFor( 3000)
一些页面要善于使用 Page.waitFor。因为有些click 事件程序触发过短会无法唤起
5.定位元素
在获取页面某个标签内的元素是比较常用的方法,可以通过querySelector 先定位到元素,然后通过 page.evaluate 执行js 原生方法来拿到标签内的文本
status_text= await page.querySelector( ".status-text")
sussces_info= await page.evaluate( '(element) => element.textContent', status_text)
6.截图
有时候我们需要对页面的某一段元素进行截图,我们可以使用page.J 先定位到元素,然后调用 screenshot 进行截图
element = await page.J('.ant-table-wrapper')
now_unix_time = int(time)
image_name = 'screenshot-{}.png'.format(str(now_unix_time))
image_path = '/'.join([self.config[ "images_path"], image_name])
await element.screenshot({ "path": image_path})
截图的时候需要设置浏览器的分辨率
awaitpage.setViewport({ 'width': 1280, 'height': 720})
7.快速查找元素
很多时候我们不能通过 id、 class 来定位页面元素的具体路径,可以借助 Chrome 的开发者工具,对元素进行定位,快速的找到元素,而 Pyppeteer 提供了多种方式查找元素,如选择器、xpath
例如:
awaitpage.querySelector # 选择器方式定位元素
awaitpage.xpath # xpath 方式定位元素
8.Page.waitFor
page.waitFor(selectorOrFunctionOrTimeout[, options[, …args]]) 下面三个的综合 API
page.waitForFunction(pageFunction[, options[, …args]]) 等待 pageFunction 执行完成之后
page.waitForNavigation(options) 等待页面基本元素加载完之后,比如同步的 HTML, CSS, JS 等代码
page.waitForSelector(selector[, options]) 等待某个选择器的元素加载之后,这个元素可以是异步加载的。
9.使用工具自动生成代码
如果你对编写这种枯燥乏味的元素定位感到厌烦,不妨试试Chrome 的插件 Puppeteer recorder ,他可以录制你的页面操作,当然很多时候并不是很准,但是通过它来辅助开发,可以大大提升你的开发效率。
10.执行程序
由于是异步的,因此我们需要通过异步的方式来调用,同时使用 loop的create_task 方法获取回调拿到返回值。
loop= get_event_loop
task= loop.create_task(sync_payment_platform.get_page_image)
image_name= loop.run_until_complete(task)
11.无头模式下的调试
在我们爬取一些网站时候发现在正常有Headless 的情况下可以得到最终的效果,但是在无头模式下会拿不到元素,提示超时。报类似 下面这样的超时错误。
Waitingforselector" #indexPageViewName> div.content-view> div> div> div.left-view> div.searchform.clearfix> div:nth-child(1)> div:nth-child(3)> div> div> div.field-left" failed: timeout30000 msexceeds.
这种情况下我们可以通过上面说的截图的方式进行Debug,看下当前报错的页面是否与实际页面一致,建议配置上 User-Agent。因为某些情况下系统会把页面当成移动端来访问,导致获取到的页面元素与实际不一致。
awaitpage.setUserAgent( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36')
12.pypuppet 整合 requests
很多时候,一些系统都会提供接口,如果我们能够直接请求这些接口,效率会更高,但是内部系统会使用非常严格的校验,普通的登录方式是走不通的。不过 pypuppet 可以帮我们绕过鉴权限制,并拿到对应系统的cookies。
cookies = await page.cookies
cookies_info = {}
for i in cookies:
key_name = i[ "name"]
value_name = i[ "value"]
cookies_info[key_name] = value_name
当我们拿到 cookies 后我们就可以通过 requests 模拟 HTTP 请求了,这样在一些非异步加载的页面下可以直接爬取接口,节省了大量的时间和精力。
response= self.request_session.post(url, headers=headers, json=payload, cookies=cookies_info)
这里可以把缓存信息写到 Redis 中去,设置下过期时间,这样只需要在首次进行登录,后面直接读取cookies 进行请求,与此同时,一些网站的请求头中加了一些自定义的头,如果缺少这些头,则无法进行请求,这时候,我们可以通过page.on 来拦截请求或响应信息,例如抓取特定的url,拿到对应的 headers 将其进行缓存,然后读取 headers 信息放到请求头中去,完美的绕过鉴权。
async defintercept_response( self, res):
ifres.request.url == self.config[ "api_url"] + "api/web/emp/business:
print(f"获取请求头 {res.request.headers} ")
self.redis_connect.set_redis("key ", str(res.request.headers))
async def login_meike(self):
……
page.on('response', self.intercept_response)
13.服务器环境依赖
我们是将其部署在虚拟机上,由于单位提供的镜像非常精简,如果想让程序能够在无头模式下运行,只需要安装 Xvfb 即可,Xvfb是一个实现了X11显示服务协议的显示服务器。不同于其他显示服务器,Xvfb在内存中执行所有的图形操作,不需要借助任何显示设备。执行下面的命令即可安装:
yum-y install Xvfb
然后默认centos 的源中是没有 Chromium 的,需要安装 epel-release 然后执行:
yum -y installepel- release
yum -y installChromium
接着就可以部署到服务端运行了。
不过需要注意了,如果你的服务器没有安装中文字体。Chromium 中会显示方块字。这个时候只需要安装上对应的中文字体就行
yum-y groupinstall chinese-support
yum-y groupinstall Fonts
案例演示
下面是一个使用 pyppeteer 登录某网站,我们可以看到这个网站需要输入手机号、密码还有
那么我们怎么使用 Pyppeteer 开完成呢?
asyncdefopen_browser(self):
browser = awaitlaunch(
{ 'executablePath': "c:/chrome-win/chrome.exe",
'headless': False, # 是否启用无头模式,False 会打开浏览器,True 则在后台运行
"autoClose": True,
"ignoreDefaultArgs": [ "--enable-automation"],
"args": [
'--disable-extensions',
'--hide-scrollbars',
'--disable-bundled-ppapi-flash',
'--mute-audio',
'--no-sandbox', # --no-sandbox 在 docker 里使用时需要加入的参数,不然会报错
'--disable-setuid-sandbox',
'--disable-gpu'
],
'dumpio': True
})
awaitpage.setViewport({ 'width': 1920, 'height': 1080}) # 定义浏览器的窗口大小,如果太小了,则页面显示不全
awaitpage.evaluateOnNewDocument( 'Object.defineProperty('
'navigator, "webdriver", {get: => undefined})')
awaitpage.setUserAgent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36')
return[page, browser]
定义一个函数用户打开网站,输入用户名和密码以及验证码 page.type 中的元素地址,我们可以参考上面快速查找元素部分来通过chrome 开发者模式调试获取元素路径,我们可以看到这个网站他的id 为 userLoginCode 的 input 有2个,但是他们的name 是不一样的,所以我们可以这样去选择。
#personLi> td> div> input[name=loginCode]
下面是这个登录函数的代码:
asyncdeflogin(self):
#调用上面的函数打开浏览器
page, browser = awaitself.open_browser
login_url = "https:/xxx.cn/xxx/"
# 打开网站
awaitpage.goto(login_url)
login_random_time = randint( 30, 150)
# 获取页面验证码的图片元素并截图
verification_code = awaitpage.querySelector( "#userGetValidCodeImg > a > img")
images_path = "images/verification_code.png"
awaitverification_code.screenshot({ 'path': images_path})
# 通过 OCR 识别验证码,如果返回False 则不断重试,直到登录成功,如果返回Ture,则输入用户名、密码、验证码进行登录。
code = awaitself.ocr_verification_code(images_path)
print( f"当前验证码 {code}")
ifcode isFalse:
whileTrue:
awaitpage.reload
ifawaitself.login_yaohao:
break
else:
# 填写用户名、密码和验证码并点击登录按钮
awaitpage.type( '#personLi > td > div > input[name=loginCode]', self.username,
{ 'delay': login_random_time - 50})
awaitpage.type( '#userPassword', self.password, { 'delay': login_random_time - 50})
awaitpage.type( '#userValidCode', code, { 'delay': login_random_time - 50})
awaitpage.click( '#userLoginButton')
awaitpage.waitFor( 2000)
cookies = awaitpage.cookies
cookies_info = {}
fori incookies:
key_name = i[ "name"]
value_name = i[ "value"]
cookies_info[key_name] = value_name
self.redis_connect.set_redis( "yaohao", "cookies", str(cookies_info), ex= 3600)
awaitbrowser.close
returncookies_info
通过上述方式我们登录成功后,就可以拿到cookies。并可以通过定义一个 Session,然后去请求啦。
def__init__( self):
super.__init_ _
self.request_session = Session
好了,以上就是关于使用Python 制作 RPA 机器人的分享。返回搜狐,查看更多
责任编辑:
python开发rpa_几步教你用 Python 制作一个 RPA 机器人!相关推荐
- 几步教你用 Python 制作一个 RPA 机器人!
作者 | 阿文 出品 | CSDN(ID:CSDNnews) 头图 | CSDN下载自东方IC 繁琐且重复的工作 在我们日常的工作中,有很多事情是重复且繁琐的,组织内部不同的部门开发出来的系统相互之间 ...
- 用rpa必须会用python语言_几步教你用 Python 制作一个 RPA 机器人!
那么我们能不能通过机器去自动完成这些固定流程且繁琐的工作呢?答案是肯定的.现阶段,我们可以通过引入 RPA 来实现整个流程的打通. 什么是 RPA RPA 是机器人流程自动化的简称,听起来很高大上的名 ...
- 如何用python开发游戏_手把手教你用Python完成一个控制台小游戏-阿里云开发者社区...
很多人想学Python程序设计或者已经了解过一点Python程序设计基础,却没办法开发出一个项目. 今天,通过演示一个简单的控制台小游戏制作,手把手教你如何用Python编写一个游戏程序,即便你是个新 ...
- 【游戏开发创新】手把手教你使用Unity制作一个高仿酷狗音乐播放器,滨崎步,旋律起,爷青回(声音可视化 | 频谱 | Audio)
文章目录 一.前言 二.获取UI素材 三.使用UGUI制作界面 1.界面布局 2.账号圆形头像 3.搜索框 4.调节UI层 5.黑色按钮悬浮高亮效果 6.纯文字按钮 7.滚动列表自适应 8.歌名与视频 ...
- 三步教你用Node做一个微信哄女友(基友)神器,小白可上手
前言 不知道大家最近有没有被python版的<微信每日说>刷屏呢,他可是霸占了github的python热门快两周了.我们前端的小伙伴是不是也看着有点眼馋呢,因为毕竟是不那么熟悉的pyth ...
- Python开发【第二篇】:初识Python
Python开发[第二篇]:初识Python Python简介 Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为 ...
- 480集课程-打通Python开发的任督二脉 轻松掌握Python高级开发技术 Python超级学科课程
480集课程-打通Python开发的任督二脉 轻松掌握Python高级开发技术 Python超级学科课程 ===============课程目录=============== ├─(1) 01-Pyt ...
- VSCode配置python开发环境无法找到自己设置的python编译器
VSCode配置python开发环境无法找到自己设置的python编译器 前言 一. 分别安装VScode和python 二.vscode配置python环境 1.在vscode里安装官方python ...
- 手把手教你做第一个RPA机器人流程
手把手教你做第一个RPA机器人流程 第一步:下载&安装RPA工具 第二步:新建第一个自动化流程 第三步:开始详细配置流程 简单介绍一下艺赛旗RPA界面 开始流程配置 第四步:总结 第一步:下载 ...
最新文章
- SLAM算法&技术之Gauss-Newton非线性最小二乘算法
- JS中定义式函数与变量时函数的差别
- java做一个客房管理系统定制_Java实现酒店客房管理系统
- java实用教程——组件及事件处理——概述
- 64位Windows2003 Enterprise sp2 上64位Oracle10.2.0.1升级到Oracle10.2.0.3具体步骤
- python 几何教学_opencv-python教程学习系列11-几何变换
- 组装复杂json请求数据和解析复杂json数据
- ubuntu16.04系统上安装CAJViewer方法步骤教程详解
- 夜神安卓模拟器安装xposed框架
- hadoop的学习之一
- 常见的系统故障及排除
- MOSSE相关滤波算法学习笔记
- CodeForces 592C (胡搞)
- 多功能频谱分析仪TFN RMT系列,满足您对频谱分析仪的多种幻想。
- Understanding the Users and Videos by Mining a Novel Danmu Dataset
- 记2014“蓝桥杯全国软件大赛决赛北京之行
- 【Docker 那些事儿】容器监控系统,来自Docker的暴击
- linux的create命令,createuser命令
- Hubot:来自GitHub的聊天机器人
- LSB算法的实现(带简单界面)