简单记录
时间相关
获取格式化的当前时间
dtmNowTime = Time.Now()
strFormatCurrentTime = Time.Format(dtmNowTime, "yyyy-MM-dd hh:mm:ss")
Log.Info("当前时间:" & strFormatCurrentTime)
strFormatCurrentTime = Time.Format(Time.Now(), "yyyy-MM-dd hh:mm:ss")
Log.Info("当前时间:" & strFormatCurrentTime)
对日期时间进行加减
减一年:Time.DateAdd(“yyyy”, -1, dtmNowTime) 减一季度:Time.DateAdd(“q”, -1, dtmNowTime) 减一月:Time.DateAdd(“m”, -1, dtmNowTime) 减一星期:Time.DateAdd(“ww”, -1, dtmNowTime) 减一天:Time.DateAdd(“d”, -1, dtmNowTime) 减一小时:Time.DateAdd(“h”, -1, dtmNowTime) 减一分钟:Time.DateAdd(“n”, -1, dtmNowTime) 减一秒:Time.DateAdd(“s”, -1, dtmNowTime)
dtmNowTime = Time.Date()
dtmYesterdayTime = Time.DateAdd("d", -1, dtmNowTime)
strFormatYesterdayTime = Time.Format(dtmYesterdayTime , "yyyymmdd")
加的话,把 -1 改成 1
数据操作相关
字符相关
判断指定字符是否在字符串内
判断 a 是否在 asdfghjll 内。没有 in 或者 contains 之类的可以使用,只能是获取一个字符串在另一个字符串中首次出现的位置。
InStr("asdfghjll", "a", 0, False)
但是返回的是位置(数字),不能直接用于判断,所以需要再加个判断,返回的才是 Ture 或者 False
InStr("asdfghjll", "a", 0, False) > 0
https://learn.microsoft.com/zh-cn/office/vba/language/reference/user-interface-help/instr-function
数组相关
获取数组的元素数量
UBound(array)
数组头部添加元素
Unshift(array, "123")
数组过滤
arrFilePath = Filter(arrFilePath, "123", false)
数组克隆
arrNewName = Clone(arrName)
使用变量赋值命令操作数组时,改变赋值后的数组,原数组也发生变化
字符串分割成数组
以指定字符串做分割
arrRet = Split("qfgh|ert","|")
无指定分隔符,每个字符变为数组的一个元素
arrRet = Regex.FindAll("qfgh|s的发ert","[\\s\\S]")
数组合并成字符串
strNewName = Join(arrNewName, "、")
数据表相关
数据表筛选
字段包含指定字符串
objDatatable = Datatable.QueryDataTable(objDatatable,"列名.str.contains('人民币')")
字段包含指定字符串,指定字符串是变量
objDatatable = Datatable.QueryDataTable(objDatatable,"列名.str.contains(\""&筛选关键词&"\")"
字段等于指定字符串
objDatatable = Datatable.QueryDataTable(objDatatable,"列名=='人民币'")
objDatatable = Datatable.QueryDataTable(objDatatable,"列名==" & strCurrencyType)
字段为空。
objDatatable = Datatable.QueryDataTable(objDatatable,"列名.isnull()")
集合相关
集合初始化时赋值
ObjSet = Set.Create(["1","2"])
字典相关
字典初始化时赋值
dicName = {"1":2,"A":3}
文件/文件夹相关
在指定文件夹下,查找指定名称的文件
arrFilePath = File.SearchFile('''文件夹路径''', "文件名称*.xls*", True)
在指定文件夹下,获取文件或文件夹列表
文件列表,返回的是文件名称
arrFilePath = File.DirFileOrFolder(strInputFolderPath, "file", {"hasPath": false})
文件夹列表,返回的是文件夹的绝对路径
arrFilePath = File.DirFileOrFolder(strInputFolderPath, "file", {"hasPath": True})
文件和文件夹列表,返回的是文件和文件夹的绝对路径
arrFilePath = File.DirFileOrFolder(strInputFolderPath, "fileandfolder", {"hasPath": True})
获取文件扩展名
strExtensionName = File.ExtensionName('''C:\Users''')
获取文件/文件夹名称
File.BaseName('''C:\Users''')
正则相关
正则测试是否能找到
Regex.Test(strFileName, "台账表.*.xls.*")
JS 相关
隐藏元素
document.querySelector(".QuestionButtonGroup").style.display = "none"
document.querySelector(".QuestionButtonGroup").style.visibility = "hidden"
document.querySelector(".QuestionButtonGroup").style.opacity = 0
https://developer.mozilla.org/zh-CN/docs/Web/API/Document/querySelector
显示元素
document.querySelector(".QuestionButtonGroup").style.display = "block"
document.querySelector(".QuestionButtonGroup").style.visibility = "visible"
document.querySelector(".QuestionButtonGroup").style.opacity = 1
获取 iframe 里面的元素
document.querySelector("#iframeResult").contentDocument.querySelector("img")
获取 iframe 里面的元素属性
document.querySelector("#iframeResult").contentDocument.querySelector("img").alt
Python 相关
pip install 的时候临时换源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 需要安装的依赖库
pyautogui 实现鼠标移动到绝对坐标
import pyautogui
# 移动鼠标,duration为持续时间
pyautogui.moveTo(100, 100, 0.25) # 持续时间为 0.25 秒,移动到 (100,100),
pyautogui 实现鼠标相对移动
import pyautogui
# pyautogui.FAILSAFE = False # 默认为 True,当鼠标位于主显示器的四个角中的任何一个位置,就会报错;Fasle 为不启用自动防故障,
# pyautogui.PAUSE = 2.5 # 默认 0.1 秒,每个 pyautogui 命令的间隔停顿 0.1 秒
pyautogui.moveRel(500, 0, duration=2) # 从当前位置移动鼠标,持续时间为 2 秒
pyautogui.moveTo(100, 100, 2, pyautogui.easeInQuad) # 开始很慢,不断加速
pyautogui.moveTo(100, 700, 2, pyautogui.easeOutQuad) # 开始很快,不断减速
pyautogui.moveTo(700, 100, 2, pyautogui.easeInOutQuad) # 开始和结束都快,中间比较慢
import pyautogui
pyautogui.moveTo(None, 500) # 坐标传 None 值,表示当前鼠标光标位置
pyautogui.move(-30, None)
pyautogui.move(-30, 0)
https://pyautogui.readthedocs.io/en/latest/
https://pyautogui.readthedocs.io/en/latest/mouse.html#tween-easing-functions
正则解析中文时间
用正则的思路去实现,代码比较长
import re
import time
from datetime import datetime
class ParseTimeError(Exception):
"""解析时间失败"""
def get_days_ago_date(days, date_format='%Y-%m-%d %H:%M:%S'):
days = int(days)
subtractTime = time.time() - days * 24 * 60 * 60
formatTime = time.strftime(date_format, time.localtime(subtractTime))
return formatTime
def get_hours_ago_date(hours, date_format='%Y-%m-%d %H:%M:%S'):
hours = int(hours)
subtractTime = time.time() - hours * 60 * 60
formatTime = time.strftime(date_format, time.localtime(subtractTime))
return formatTime
def get_mins_ago_date(mins, date_format='%Y-%m-%d %H:%M:%S'):
mins = int(mins)
subtractTime = time.time() - mins * 60
formatTime = time.strftime(date_format, time.localtime(subtractTime))
return formatTime
def parse_time(dateTimeText):
"""根据传入的时间文本进行解析,获取对应的日期时间
:param dateTimeText: 需要解析的时间文本
:return: 解析到的日期时间
:raises: 解析失败时抛出 ParseTimeError
"""
dateTimeText = str(dateTimeText)
print("用于解析的时间文本:" + dateTimeText)
transformTime = ""
try:
transformTime = datetime.strptime(dateTimeText, '%Y-%m-%d')
return dateTimeText
except ValueError:
print("输入日期文本不为 yyyy-mm-dd 格式,进行后续处理")
if '天前' in dateTimeText:
a = re.findall('(.*?)天前', dateTimeText)
transformTime = get_days_ago_date(a[0], date_format='%Y-%m-%d')
if '前天' in dateTimeText:
interTime = 3
transformTime = get_days_ago_date(interTime, date_format='%Y-%m-%d')
if '昨天' in dateTimeText:
interTime = 1
transformTime = get_days_ago_date(interTime, date_format='%Y-%m-%d')
if '小时前' in dateTimeText:
a = re.findall('(.*?)小时前', dateTimeText)
transformTime = get_hours_ago_date(a[0], date_format='%Y-%m-%d')
if '分钟前' in dateTimeText:
a = re.findall('(.*?)分钟前', dateTimeText)
transformTime = get_mins_ago_date(a[0], date_format='%Y-%m-%d')
if '秒前' in dateTimeText:
interTime = 0
transformTime = get_mins_ago_date(interTime, date_format='%Y-%m-%d')
if '刚刚' in dateTimeText:
interTime = 0
transformTime = get_mins_ago_date(interTime, date_format='%Y-%m-%d')
if (not transformTime):
raise ParseTimeError(f'解析时间: {dateTimeText},失败')
return transformTime
print(parse_time('2023-03-15'))
print(parse_time('7天前'))
print(parse_time('5天前'))
print(parse_time('4天前'))
print(parse_time('前天'))
print(parse_time('昨天'))
print(parse_time('20小时前'))
print(parse_time('10小时前'))
print(parse_time('10分钟前'))
print(parse_time('10秒前'))
print(parse_time('今晚加班'))
print(parse_time('17小时前'))
用 sinan 实现解析中文时间
from sinan import Sinan
obj = Sinan('5秒前')
result = obj.parse()
print(result)
print(result['datetime'][0])
https://github.com/yiyujianghu/sinan
返回信息:
参数名 | 含义 | 示例 |
---|---|---|
datetime | 日期时间信息 | ‘2020-08-05 17:00:00’ |
length | 长度信息 | (5000.0, ‘m’) |
weight | 质量信息 | (2.0, ‘kg’) |
time | 时间信息 | (5400.0, ‘s’) |
temperature | 温度信息 | (20.0 ‘℃’) |
money | 钱数信息 | (300.0, ‘元’) |
people | 人数信息 | (2.0, ‘人’) |
phone_num | 手机号码 | ‘18610086138’ |
identification | 身份证号 | ‘110108199703069999’ |
解析时间
from dateutil.parser import parse
logline = "INFO 2020-01-01T00:00:01 ."
timestamp = parse(logline, fuzzy=True)
print(timestamp)
检测编码
import chardet
print(chardet.detect(b'Hello, world!'))
data = '离离原上草,一岁一枯荣'.encode('gbk')
print(chardet.detect(data))
data = '离离原上草,一岁一枯荣'.encode('utf-8')
print(chardet.detect(data))
获取所有进程名称
import psutil
pids = psutil.pids()
for pid in pids:
p = psutil.Process(pid)
print("pid:%d,%s" % (pid, p.name()))
结束包含指定名称的进程
import os
import time
import psutil
os.startfile(r"C:\Windows\System32\PhotoScreensaver.scr") # 启动屏保
time.sleep(10)
pids = psutil.pids()
for pid in pids:
p = psutil.Process(pid)
if ".scr" in p.name():
print(pid, p.name())
p.terminate() # 终止进程
# p.kill() # 杀掉进程
跨工作簿复制工作表
import xlwings as xw
def copy_sheet(source_file_path, target_file_path, sheet_name):
"""读取来源 Excel 文件,复制指定 Sheet 到目标 Excel 文件
:param source_file_path: 来源 Excel 文件的路径
:param target_file_path: 目标 Excel 文件的路径
:param sheet_name: 需要复制的 Sheet 名称
"""
app = xw.App(visible=True) # 打开 Excel,visible=True 可见,visible=False,不可见
# 打开来源 Excel 文件
source_book = xw.Book(source_file_path)
print("已打开来源 Excel 文件,路径:" + source_file_path)
# 打开目标 Excel 文件
target_book = xw.Book(target_file_path)
print("已打开目标 Excel 文件,路径:" + target_file_path)
# 复制指定 Sheet 到目标 Excel。-1代表复制到最后一个,0代表复制到倒数第二个
source_book.sheets[sheet_name].copy(after=target_book.sheets[-1])
print(f"已复制:{sheet_name} 到 {target_file_path}")
target_book.save()
source_book.save()
target_book.close()
source_book.close()
app.quit() # 关闭excel
https://docs.xlwings.org/zh_CN/latest/quickstart.html
Uibot 密文解密
UiBot 读取 commander 的凭据或者是凭据管理器的凭据,读取出来的密码是密文,需要解密才能获取到明文。
但是为什么这代码要这么写,我不懂,给到我的代码就这样,我就格式化了一下代码。
try:
import UiBot
except Exception as e:
class Temp():
def GetString(self, strPath):
return ""
UiBot = Temp()
def _Decrypt(pwd):
UiBot.PushContext()
try:
# 解密失败 抛出异常
pwd = UiBot.InvokeRobotCore(0, 'GetStringFromSecText', ['', pwd])
except:
pass
UiBot.PopContext()
return pwd
CMD命令行相关
显示进程列表
tasklist
以 csv 格式显示进程列表,默认格式是table
tasklist /fo csv
筛选出谷歌浏览器的进程
tasklist /fi "IMAGENAME eq chrome.exe"
筛选出 chrome 开头的进程
tasklist /fi "IMAGENAME eq chrome*"
筛选出包含 msedge 的进程
tasklist | findstr /i msedge
筛选出包含 .scr 的进程
tasklist | findstr /i \.scr
筛选出以 .scr 结尾的进程
tasklist | findstr /i "\.scr\>"
https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/tasklist
https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/findstr
筛选出 .exe 的进程
wmic Process Where "Name like '%.exe'" Get Name
杀掉进程
kill 掉谷歌浏览器的进程
Taskkill /f /im chrome.exe
kill 掉屏保
Taskkill /f /t /im PhotoScreensaver.scr
kill 掉 msedge 开头的进程
Taskkill /f /fi "IMAGENAME eq msedge*"
Taskkill /f /t /im msedge*
kill 掉包含 msedge 的进程
for /f %a in ('tasklist ^| findstr /i msedge') do taskkill /f /fi "imagename eq %a"
kill 掉 .scr 结尾的进程,推荐 tasklist 的方式
for /f %a in ('tasklist ^| findstr /i "\.scr\>"') do taskkill /f /fi "imagename eq %a"
for /f %a in ( 'wmic Process Where "Name like '%.scr'" Get Name') do taskkill /f /fi "imagename eq %a"
https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/taskkill
https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/findstr
其他
截全屏(元素截图)
显示桌面背景的窗口类名称是 Program,它是 z-index 最低的顶级窗口,所以始终在所有窗口下面。而显示桌面图标的窗口类名称是 SHELLDLL_DefView,是它的子窗口。
SysListView32 和 SHELLDLL_DefView 是管理和显示桌面图标的。Progman 是显示出来的总桌面,也是总程序.
只需要给 Program Manager **窗口发送一个消息 **0x52C ,就可以将 Program Manager 拆分为多个窗口,分别是 Program Manager **窗口和两个 **WorkerW 窗口。
https://blog.csdn.net/qq_40036189/article/details/108210747
https://www.cnblogs.com/choumengqizhigou/p/15702980.html
http://suquark.github.io/lecture/2017/07/01/wallpaper_engine-DIY.html
实际的使用中,建议只选择到 Program Manager
这个顶级窗口,再下面一层的就不再选择。
实际情况下,用 Spy++ 查看过,存在没有 SysListView32 和 SHELLDLL_DefView 的情况,Windows 多窗口分屏(左右分屏)即可复现。
截全屏(快捷键 PrintScreen)
截图出来的文件会很大,好几M,不太建议。
Keyboard.Press("PrintScreen", "press", [],{"iDelayAfter": 300, "iDelayBefore": 200, "sSimulate": "simulate"})
Clipboard.SaveImage('''C:\Users\lbj\Desktop\test.jpg''')
杀屏保
如果无法通过设置来调整屏保的话,只能是通过杀掉屏保进程的方式解决。
屏保为 .scr 文件,系统自带的屏保存放在 C:\Windows\System32
文件夹下,可以直接 App.Kill 杀掉屏保
App.Run('''C:\Windows\System32\PhotoScreensaver.scr /s''',0,1) // 打开屏保
Delay(5000)
App.Kill("PhotoScreensaver.scr") // 杀掉屏保
防止电脑锁屏
如果无法通过设置来防止电脑进入休眠,只能使用以下的方式。
https://www.appinn.com/mouse-jiggler-2/
https://github.com/arkane-systems/mousejiggler
已验证过可行,shell:startup ,把快捷方式加到开机自启,快捷方式添加:-j -m -z 即可
快捷方式,修改属性,把快捷方式的目标 修改为类似:”C:\Program Files\MouseJiggler.exe” -j -m -z
仅对当前用户生效:shell:startup 对所有用户生效:shell:common startup
或者弄个视频一直播放
微软的 PowerToys Awake
短信通知
用起来还可以,一个post请求就能发送短信,0.1 元一条:http://console.smsbao.com/#/index
阿里云的,签名和模板可能不好通过申请:https://dysms.console.aliyun.com/overview
模拟操作、后台操作、系统消息三种操作类型的区别
在Creator中设计RPA流程时,高频用到的命令有“点击目标”、“在目标中输入”等,在这些命令中都一个同名属性”操作类型”,分别有”模拟操作”、”后台操作”、”系统消息”这3个下拉选择项。
那么它们有什么区别,应该怎么使用呢?
1、模拟操作:指通过调用系统 api mouseevent 等实现鼠标操作,会实际移动光标 。
2、系统消息:指发送鼠标消息到目标元素,不移动光标。
3、后台操作:可以理解为调用了一次元素的鼠标响应回调函数。
那他们分别是在哪种场景下使用呢?
由上往下是底层到上层的顺序,越底层兼容性越好,上层有速度和精准的优势。
1、模拟操作 2、系统消息 3、后台操作