Frossky 发布的文章
对UiBot Creator目标选择器的研究
Creator 版本6.0.1
2024/1/8 在最新的文档中介绍了对目标的选择和目标选择器的使用
https://documents.laiye.com/rpa-guide/docs/DevGuideD1/Chapt3-Target
直接用命令里的获取目标
只适合目标的名称不会变化的. 如果目标的名称会变, 就只能用目标选择器去拆解目标.
按官方文章给出的方法, 可变目标名称一个是将aaname
改为*
, 但会增加错选的概率. 另一个是通过目标选择器(UI分析器)选择上级的不变目标, 再用获取子元素的命令获取子元素, 再从子元素中找到想要的目标.
Creator 研究版本: 5.5.0
对Chrome浏览器的选择
以鼠标点击目标
为例,
一个典型的选择器
{
wnd: [
{ cls: "Chrome_WidgetWin_1", title: "*", app: "chrome" },
{ cls: "Chrome_RenderWidgetHostHWND", title: "Chrome Legacy Window" },
],
html: [{ tag: "SPAN", parentid: "body", aaname: "idarc", idx: 0 }],
}
wnd
应为window
的缩写, 对于Chrome的窗口的选择代码死树是固定的.
html
因为对具体页面的选择.
tag
: 为选择文本的标签名
parentid
: 上级中最近一个有id的标签的id. 这儿正好是body, 但不是指body标签.
aaname
: 标签内的文字. 不加通配符是需要精确匹配的. 另外试过是支持*
和?
通配符, 用法和正则一样. 其他正则符号似乎就不支持了.
idx
: index的简称, 在parentid的标签内可能有出现了多个tag, 其中的文字也是相同的, 这个idx是第几个的意思. 从0开始计数.
如果tag能定位, 则不需要parentid, 其他的键也类似.
点击table内的一个单元格
html: [
{ tag: "TABLE", parentid: "J_Reviews" },
{ tag: "TD", tableRow: "2", tableCol: "3" },
]
html数组中的值是依次缩小搜索范围的.
定位某一个单元格TD, 出现了两个新的键名: tableRow
和tableCol
, 分别是行数和列数. 这儿注意, 行数和列数是从1
开始数的.
点击一个图片
html: [
{
tag: "IMG",
parentid: "J_Reviews",
"css-selector":
"body>div>div>div>div>div>div>div>div>div>div>table>tbody>tr>td>div>div>div>ul>li>img",
src:
"//img.alicdn.com/bao/uploaded/i4/O1CN012qd0b21L8NLDRJi8f_!!0-rat*",
},
]
这儿出现了另两个新键名:
css-selector
: css选择器. 但是这个里面没有出现id和class的选择器. 试了一下, class选择器.
似乎是不支持的.
src
: 可以写入src. 其中似乎可以使用*
通配符.
内嵌与chrome中的目标选择器JSON生成工具
参考: https://zhuanlan.zhihu.com/p/90916040?from_voters_page=true
位置在F12->Elements
,然后点击中间Styles
菜单行最后的>>
,选择UiBot
.
用Chrome自己的选择器选择目标后, 再点击Uibot
中的生成选择器
或生成选择器(CSS selector)
生成选择器JSON代码.
普通选择器样式:
{
"html": {
"tagName": "P",
"attrMap": {
"tag": "P",
"isleaf": "1"
},
"index": 24
},
"wnd": [
{
"app": "chrome",
"cls": "Chrome_WidgetWin_1",
"title": "*"
},
{
"cls": "Chrome_RenderWidgetHostHWND",
"title": "Chrome Legacy Window"
}
]
}
CSS选择器样式:
{
"html": {
"tagName": "p",
"attrMap": {
"css-selector": "body>div>div>main>div>article>div>div>p"
},
"index": 34
},
"wnd": [
{
"app": "chrome",
"cls": "Chrome_WidgetWin_1",
"title": "*"
},
{
"cls": "Chrome_RenderWidgetHostHWND",
"title": "Chrome Legacy Window"
}
]
}
未命名文档
复制这段内容后打开百度网盘App,操作更方便哦。 链接:https://pan.baidu.com/s/10Tk1aC7htd0_YI7gzJnTAw 提取码:814v
git revert: 版本回退为一个新的commit,或回退到working tree
用tortoise git的操作方式:
首先查看log, 然后选中要撤销的所有版本. 比如提交了10个版本,要回退到第7个版本, 那么就选中8, 9, 10 这三个版本, 点击右键, 选择'revert...'
EBIT、EIBTDA、ROIC、ROI、ROA、ROE等投资分析指标的说明
2020-3-1实施的新<证券法>改变
RPA培训的笔记
常见问题
- 被操作软件不支持特别大量数据导出(如超过10000条). 解决: 发现这个最大值, 并分批处理.
- 被操作网站元素变化, 主要有不同权限登录的账号的内容层级不同/网站加密导致每天随机生成一些内容反爬. 解决: 使用目标账号进行操作, 并剔除随机内容.
- 异常定位: Creator软件报错的代码位置不是真实的错误代码位置. 解决: 关键位置进行LOG跟踪
- 内存问题: 浏览器或目标软件长期运行(如超过两三天)导致内存溢出报错. 解决: 定时清空内存或者重启.
- 测试不足(权限问题). 尤其对于不同的账号操作不同的数据, 都可能由于账号权限不同, 目标数据读写权限不同导致报错. 解决: 最好使用所有目标账号对所有目标数据全部测试一遍.
RPA对账是个普遍需求
RPA对账,就是将银行流水和财务系统流水核对, 查看有无错误.
巴比伦河--River of Babylon
巴比伦河
在巴比伦河边上
我们坐在地上
噢,我们就哭了起来
我们想起了锡安啊
恶徒们!
把我们囚禁
逼我们歌唱
在这陌生的土地
我们怎能再把主的歌唱?
我们口中的言语
我们心里的冥想
今夜,在您的注视下
就请您收下吧
在巴比伦河边上
我们坐在地上
噢,我们就哭了起来
我们想起了锡安啊
后记:
我觉得默认翻译的不好,比如把Zion翻译成家乡。这其中确有思乡之情,却又不仅仅是普通的思乡之情而已。要说比较接近的情感,可能更接近南朝后主李煜的《虞美人》中的“一江春水向东流”的情感,是国破人虏阶下囚的情感;巴比伦之囚40多年,囚于其中,永不知归,是在绝望中忧伤、绝望中思乡吧!
所以这不仅仅是思乡之情,还有家国之情、民族之情,还有我们不甚熟悉的宗教之情。
这是首小时候就熟悉的歌,听上去欢快明亮动感,20多年后的今天,长大了才知道,这竟是一首忧伤的歌。现在了解了犹太人的巴比伦之囚,看过《黑客帝国》知道了锡安,才了解了歌词背后的意义。原来,旋律的欢乐是为侵略和奴隶主假装出来的欢乐,而用他们听不懂的语言,才直白地向自己的主说出心里的痛苦。
附录:原版歌词和默认翻译。
By the rivers of Babylon, there we sat down
来到巴比伦河边,我们坐在你身旁
ye-eah we wept, when we remembered Zion.
耶,我们哭泣又悲伤,当我们想起了家乡
By the rivers of Babylon, there we sat down
来到巴比伦河边,我们坐在你身旁
ye-eah we wept, when we remembered Zion.
耶,我们哭泣又悲伤,当我们想起了家乡
When the wicked Carried us away in captivity
当邪恶的人把我们抓走囚禁
Required from us a song
还强迫我们把歌唱
Now how shall we sing the lord's song in a strange land
我们怎能在他乡唱得出圣歌
When the wicked Carried us away in captivity
当邪恶的人把我们抓走囚禁
Requiering of us a song
还强迫我们把歌唱
Now how shall we sing the lord's song in a strange land
我们怎能在他乡唱得出圣歌
Let the words of our mouth and the meditations of our heart
在陌生的异国他乡让我们心里的话儿和期望
be acceptable in thy sight here tonight
在今夜向你倾叙
Let the words of our mouth and the meditation of our hearts
让我们心里的话儿和期望在今夜向你倾叙
be acceptable in thy sight here tonight
在今夜向你倾叙
By the rivers of Babylon, there we sat down
来到巴比伦河边,我们坐在你身旁
ye-eah we wept, when we remembered Zion.
耶,我们哭泣又悲伤,当我们想起了家乡
By the rivers of Babylon, there we sat down
来到巴比伦河边,我们坐在你身旁
ye-eah we wept, when we remembered Zion.
耶,我们哭泣又悲伤,当我们想起了家乡
By the rivers of Babylon (dark tears of Babylon)
来到了巴比伦河边(哭泣的巴比伦)
there we sat down (You got to sing a song)
我们坐了下来(你要唱一首歌)
ye-eah we wept, (Sing a song of love)
我们哭泣(吟唱着一首爱的歌)
when we remember Zion. (Yeah yeah yeah yeah yeah)
当我们想起家乡(是啊~~)
By the rivers of Babylon (Rough bits of Babylon)
来到巴比伦河边(来到巴比伦河边)
there we sat down (You hear the people cry)
我们坐了下来(你听到人们哭泣)
ye-eah we wept, (They need their God)
我们哭泣(他们需要上帝)
when we remember Zion. (Ooh, have the power)
当我们想起巴比伦(噢我们就得到力量)
看懂财报
技术分析理论
夫妻叹
织女牛郎生银河,
河分两边逢不得。
一年三百六十夜,
夜梦留春晨醒没。
评《金德强哪有活路》
读 江苏泗阳政务监督微群 的《金德强哪有活路》有感,从金德强和掉线的北斗不知怎么就突然想到了刘慈欣《三体》中的人类和智子,下笔成诗,只能叹之。
三体舰队太阳行,智子屏阻科技升。
百年一日皆是死,人与三体竟不同。
我之所有你难有,你之所为总显形。
我没让你今日死,但你活不到天明。
世界上最简单的会计书--读书笔记和git项目
在gitee上开了一个js项目做, 因为对于数字我实在是不敏感, 写成程序反而大大加快并加强了理解. 项目地址: https://gitee.com/littleprog/accounting
第十章的感悟如下:
- 三大比率: 成本收入比, 费用收入比, 净利率, 应该与行业均值比较, 并且与自身过往比较(趋势分析);
- 固定资产的投资最终可能很难收回, 因为固定资产(尤其是设备)都不大好卖的, 因此固定资产应该慎重投资, 应评估固定资产投入后能带来多少产出, 利润是否能很快覆盖并超出固定资产;
- 对于供应链管理, 先进先出, 减少存货库存周期及其重要. 库存长期积压, 无论对于保质期长短的存货都不是好事, 长期积压最后会直接导致资产减值;
- 应减少坏账, 评估客户和渠道的偿债能力, 坏账将直接导致利润减值;
- 现金流及其重要, 更甚于利润. 一个盈利良好的企业现金流一旦中断, 企业连一天都不能维持.
- 利润存在于账面上, 是很容易流失的;
- 提高利润其实就是老生常谈的开源节流,降本增效. 但开源和节流是矛盾的, 降低成本和费用也有可能导致销量下降(广告曝光不足/品质下降等), 而开发新产品新功能一定是会提高成本的.
最终测验90分, 第二题审题不严导致的错误.
js object对象的深度复制(深度拷贝)
这个链接https://www.javascripttutorial.net/object/3-ways-to-copy-objects-in-javascript/#:~:text=To%20copy%20an%20object%20in%20JavaScript%2C%20you%20have,the%20JSON.stringify%20%28%29%20and%20JSON.parse%20%28%29%20methods.%20提到了3个方法, 然而2个都是有问题的, 并不能深度复制.
...大法. 不行.
> a = {a:{a:{a:1}}}
{ a: { a: { a: 1 } } }
> b = {...a}
{ a: { a: { a: 1 } } }
> b
{ a: { a: { a: 1 } } }
> a.a.a.a = 2
2
> b
{ a: { a: { a: 2 } } }
>
Object.assign大法, 还是不行.
> b = Object.assign({},a)
{ a: { a: { a: 2 } } }
> a.a.a.a = 3
3
> b
{ a: { a: { a: 3 } } }
最后唯有JSON.parse/stringify大法可用了,但是感觉好粗犷...
> b = JSON.parse(JSON.stringify(a))
{ a: { a: { a: 3 } } }
> a.a.a.a = 4
4
> b
{ a: { a: { a: 3 } } }
终极对比文章,如何深度复制对象和数组 https://javascript.plainenglish.io/how-to-deep-copy-objects-and-arrays-in-javascript-7c911359b089
此文验证过, 真正正确的文章.
看完发现, 没有js原生的方案进行深度复制...
这篇文章 https://blog.logrocket.com/methods-for-deep-cloning-objects-in-javascript/ 也提出了几个新方法.
其中提到了v8原生的深度copy方式. node中也支持
const structuredClone = obj => {
return v8.deserialize(v8.serialize(obj));
};