项目背景
现在的公司是一家五六千人的机械加工类企业, 目前处在信息化转型的中级阶段, ,主要表现为, ERP,CRM,MES,OA,WMS等系统上了不少,缺乏统一的信息门户,核心系统能做到互联互通,大部分系统是孤立的,信息孤岛问题还是比较严重.
我刚来公司不久,接到的第一个项目是用Odoo开发一个小项目,两周搞定.
第二个项目就是这个销售易和云之家对接的问题,背景是这样的:
两个系统都有审批流, 领导对于在两个系统之间来回切换不满意,所以打算将crm中的待办转到OA中.
项目计划:
crm产生待办后给OA发送一条通知消息,点击消息后跳转到CRM的页面(需要单点登陆),然后在CRM的页面中处理审批流, 审批流处理完成后再给OA发送一条消息,标记之前发送的那条通知消息为已完成.
这里解决的难点有这么几个:
1 单点登陆的问题
2 crm二开本地调试环境搭建
3 crm中流程处理完之后要回调oa接口,将之前发送的消息修改状态, 消息id的定义规则也称了一个难点.
单点登陆
云之家做的还是比较好的,扩展性不错,可以在里面开发轻应用,类似于微信小程序吧.
要做的第一步是将crm包装成云之家的一个轻应用. 通过云之家单点登陆到CRM.
这里有个问题: 两家都实现了oauth2接口,但是呢实现的细节不太一样,CRM是完全通过配置连接器的方式来实现, 标准的oauth2一共分三步:
第一步: 获取code
第二步: 根据code 和 appId appScrect 获取token
第三步: 根据token获取用户信息
在最后一步获取用户信息的时候对接不上了…
原因是因为: 云之家提供的接口需要三个输入参数,用post方式,有两个在body里面,另外一个在url后面, 这种混用的方式,CRM不支持.
最好的解决办法是让云之家另外再提供一个接口,三个参数都放在body里面,这样也不影响其他的应用,也能解决问题. 可是人家未必肯干…
求人不如求己, 想了一个临时的办法, 用python写个小程序定时登陆crm, 获取token并且修改第三步请求的url地址
类似于这样: https://aaa.bbb.com?accessToken=xxxxxxxxxxx
这就用到了大名鼎鼎的selenium
selenium
这个单词的中文意思是硒,不知道为啥起了这么名字
使用selenium基本就四个步骤:
1 导入相关包,打开浏览器
PS D:\BaiduSyncdisk\7_浩信\django-oauth-toolkit12\oauth_resource> pip show selenium
Name: selenium
Version: 4.1.0
Summary:
Home-page: https://www.selenium.dev
Author:
Author-email:
License: Apache 2.0
Location: c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages
Requires: trio, trio-websocket, urllib3
Required-by:
# 导入相关的包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 打开浏览器,前提要安装了chrome
driver = webdriver.Chrome()
- 打开一个网页, 获取元素, 可以通过ID,name,css选择器,xpath等方式
# 打开网页
driver.get('https://login.xiaoshouyi.com/auc/login')
#通过name获取元素
username = driver.find_element(By.NAME,'username')
# 通过css选择器获取元素
password = driver.find_element(By.CSS_SELECTOR,'input[data-ta-key="password_input"]')
3 调用元素的方法
#填充数据
username.clear()
username.send_keys('username')
# 调用按钮点击
btn_login.click()
4 关闭浏览器
driver.quit()
selenium 的坑
坑1 新版的selenium 获取元素的方法改变了
之前的版本类似这样
username = driver.find_element_by_name(‘username’)
现在的最新版本是这样写的, 当然By支持很多中类型,id,name,css,xpath都是支持的
username = driver.find_element(By.NAME,‘username’)
`
坑2 注意iframe
当你通过各种方法都获取不到元素的时候, 大概率,这个元素内嵌在一个iframe里面,
这时候需要先切换到iframe,然后再获取元素
# 对iframe进行操作,需要用到一下种方法:
#
# switch_to_iframe() 切换到iframe上
# switch_to.frame() 切换到iframe上
# switch_to.default_content() 切换回原主页面
#定位到iframe
iframe=driver.find_element(By.CSS_SELECTOR,"#rightFrame")
#切换到iframe
driver.switch_to.frame(iframe)
坑3 适当延时
当你打开一个页面的时候,如果立刻获取元素很可能获取不到,因为网页还没加载完成,dom结构没有完全渲染, 这是会报异常, 所以适当的延时是必要的
time.sleep(2)
另外,当完成最后一步,退出浏览器之前也要增加延时,让浏览器把工作做完再关闭.
结语
这个办法只是临时的解决方案, 万一哪天销售易页面发生变动,或者登陆的时候增加了验证码,那就不灵了,最终的解决方案,要么 云之家增加一个新的API接口来跟销售易适配,要么销售易修改代码支持云之家的那张混用的传参方式.
下一篇介绍销售易本地开发环境的搭建.