Skip to content

待处理

PyQt5

安装

pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install PyQt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple

查看模块版本

python
import cv2
print(cv2.__version__)

pypi镜像包

bash
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xxx

python执行py文件报错

bash
This program needs access to the screen. Please run with a
Framework build of python, and only when you are logged in
on the main display of your Mac.

解决办法

pythonw xxxx.py

安装xxx.whl的安装包

bash
pip install xxx.whl

参考项目

80个Python练手项目列表 https://www.lanqiao.cn/questions/102676/?utm_source=baidu&utm_medium=cpc&utm_campaign=python&utm_term=keywords

ftp部署项目

python
#coding: utf-8
import os
from ftplib import FTP
import time
# 参考 https://www.cnblogs.com/xiao-apple36/p/9675185.html
# 上传指定的文件到指定的目录下

def ftpconnect(host,port, username, password):
    ftp = FTP()
    # ftp.set_debuglevel(2)
    ftp.connect(host, port)
    ftp.login(username, password)
    return ftp

#从ftp下载文件
def downloadfile(ftp, remotepath, localpath):
    print("download:",remotepath)
    bufsize = 1024
    fp = open(localpath, 'wb')
    ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize)
    ftp.set_debuglevel(0)
    fp.close()

#从本地上传文件到ftp
def uploadfile(ftp, remotepath, localpath):
    bufsize = 1024
    fp = open(localpath, 'rb')
    ftp.storbinary('STOR ' + remotepath, fp, bufsize)
    ftp.set_debuglevel(0)
    fp.close()

def help():
    # ftp.mkd(pathname)  # 新建远程目录
    pass

def get_image_info(info):
    info_list = [item for item in info.split(" ") if item != '']
    return info_list[8],info_list[4]

vr_root_path_html = '/CTU_VR_2.0/web/Ctu_Vr.Manage/Files/vr'
vr_root_path_js = '/CTU_VR_2.0/web/Ctu_Vr.Manage/Files/contents/vr/js'
vr_root_path_css = '/CTU_VR_2.0/web/Ctu_Vr.Manage/Files/contents/vr/css'
vr_root_path_json_config_liugou = '/CTU_VR_2.0/web/Ctu_Vr.Manage/Files/vr/cunluo/liugou'

projects = {
    "liugou_demo":[
            ("/Volumes/CTU/ctu_code/CTU_DangWei_H5/vr全景/Files/vr/cunluo2.html",os.path.sep.join([vr_root_path_html,"cunluo2.html"])),
            ("/Volumes/CTU/ctu_code/CTU_DangWei_H5/vr全景/Files/contents/vr/js/cunluo2.js",os.path.sep.join([vr_root_path_js,"cunluo2.js"])),
            ("/Volumes/CTU/ctu_code/CTU_DangWei_H5/vr全景/Files/contents/vr/css/cunluo2.css",os.path.sep.join([vr_root_path_css,"cunluo2.css"])),
            # ("/Volumes/CTU/ctu_code/CTU_DangWei_H5/vr全景/Files/vr/cunluo/liugou/info2.json",os.path.sep.join([vr_root_path_json_config_liugou,"info2.json"])),
    ]

}
backup_dir = "/Users/wangxiaomin/my_code/ctu_robot/backup"

# 先备份
def backup(ftp,remote_path):
    filename = os.path.basename(remote_path)
    version = time.strftime("%Y%m%d%H%M%S", time.localtime())
    pre = filename.split(".")[0]
    ext = filename.split(".")[1]
    filename = pre+"_"+version +"."+ext
    save_path = os.path.sep.join([backup_dir,filename])
    downloadfile(ftp, remote_path, "%s" % (save_path))

def run():
    ftp = ftpconnect("vr.jzhu.cn", 210, "wangxiaomin_ftp", "Ctu202107#")
    for item in projects['liugou_demo']:
        local_path,remote_path = item
        if not os.path.exists(local_path):
            print("%s 不存在,退出",local_path)
            break
        # 备份
        backup(ftp,remote_path)
        uploadfile(ftp,remote_path,local_path)
    ftp.quit()
if __name__ == "__main__":
    run()

下载blob文件

python
import os
import time
import random
with open("video5.txt",'r') as file:
    lines = file.readlines()
    title = None
    video = None
    for i in range(0,len(lines)):
        if i % 2 == 0:
            title = lines[i]
        elif i % 2 == 1:
            video = lines[i]

        if title is not None and video is not None:
            title = title.replace("\n","").replace(" ","")
            video = video.replace("\n","").replace(" ","")
            video_path = "/Volumes/CTU/72全景项目/everpano/course_%s.mp4"%(title)
            if os.path.exists(video_path):
                continue
            cmd = "ffmpeg -i %s %s"%(video,video_path)
            print(cmd)
            os.system(cmd)
            sleep_seconds = int(random.random()*10)
            print("sleep ",sleep_seconds)
            time.sleep(sleep_seconds)

            title = None
            video = None

日志

python
from logging import getLogger, INFO
from concurrent_log_handler import ConcurrentRotatingFileHandler

log = getLogger()
# Use an absolute path to prevent file rotation trouble.
logfile = os.path.abspath("diff_project.log")
# Rotate log after reaching 512K, keep 5 old copies.
rotateHandler = ConcurrentRotatingFileHandler(logfile, "a", 1024*1024, 5)
log.addHandler(rotateHandler)
log.setLevel(INFO)

autoit

安装python+autoit

pip install pyautoit

autoit安装包: http://log.jzhu.cn:10001/autoit-v3-setup.exe

参考文档

官网文档: https://pypi.org/project/PyAutoIt/

https://www.cnblogs.com/cynthia59/p/8920700.html

源代码: https://github.com/jacexh/pyautoit

ProcessControl

python
import autoit

class ProcessControl(object):
    '''
    AutoIt进程相关操作
    '''
    def __init__(self, processName):
        '''
        Constructor
        '''
        self.processName = processName

    def close(self):
        '''
        :description 终止某个进程
        :return 1:成功; 0:失败.
        '''
        return autoit.process_close(self.processName)

    def exists(self):
        '''
        :description 检查指定进程是否存在
        :return PID:成功; 0:进程不存在.
        '''
        return autoit.process_exists(self.processName)

MouseControl

python
import autoit

class MouseControl(object):
    '''
    AutoIt鼠标相关操作
    '''
    def __init__(self):
        '''
        Constructor
        '''

    def click(self, title, text, x, y, button="main", clicks=1):
        '''
        :description 执行鼠标点击操作
        '''
        pos = autoit.win_get_pos(title, text=text)
        autoit.mouse_click(button, x + pos[0], y + pos[1], clicks=clicks)

    def move(self, title, text, x, y):
        '''
        :description 移动鼠标指针
        '''
        pos = autoit.win_get_pos(title, text=text)
        autoit.mouse_move(x + pos[0], y + pos[1])

    def drag(self, title, text, x1, y1, x2, y2):
        '''
        :description 执行鼠标拖拽操作
        '''
        pos = autoit.win_get_pos(title, text=text)
        autoit.mouse_click_drag(x1 + pos[0], y1 + pos[1], x2 + pos[0], y2 + pos[1])

    def wheel(self, direction="up"):
        '''
        :description 产生向上或向下滚动鼠标滚轮事件.仅支持NT/2000/XP及更高.
        '''
        autoit.mouse_wheel(direction)

mouseControl.py

WinControl

python
import autoit

class WinControl(object):
    '''
    AutoIt窗口相关操作
    '''

    def __init__(self, title, text=''):
        '''
        Constructor
        '''
        self.title = title
        self.text = text

    def activate(self):
        '''
        :description 激活指定的窗口(设置焦点到该窗口,使其成为活动窗口).
        :return PID:窗口存在; 0:窗口不存在.
        '''        
        return autoit.win_activate(self.title, text=self.text)

    def close(self):
        '''
        :description 关闭指定窗口.
        :return 1:成功; 0:窗口不存在.
        '''        
        return autoit.win_close(self.title, text=self.text)

    def exists(self):
        '''
        :description 检查指定的窗口是否存在.
        :return 1:窗口存在; 0:窗口不存在.
        '''
        return autoit.win_exists(self.title, text=self.text)

    def getPos(self):
        '''
        :description 获取指定窗口的坐标位置和大小等属性.
        :return Returns left, top, right, bottom    (x1,y1,x2,y2)
        '''
        return autoit.win_get_pos(self.title, text=self.text)

    def getProcess(self):
        '''
        :description 获取指定窗口关联的进程ID(PID).
        :return PID:成功, -1:失败.
        '''
        return autoit.win_get_process(self.title, text=self.text)  

    def getText(self, buf_size=256):
        '''
        :description 获取指定窗口中的文本.
        :return  指定窗口里包含的文本:成功; 0:失败(没有匹配的窗口).
        '''        
        return autoit.win_get_text(self.title, buf_size, text=self.text)

    def kill(self):
        '''
        :description 强行关闭指定窗口.
        :return  1:无论成功失败.
        '''        
        return autoit.win_kill(self.title, text=self.text)

    def move(self, x, y, width, height):
        '''
        :description 移动指定的窗口或调整窗口的大小.
        :return PID:成功, 0:失败(窗口不存在).
        '''
        return autoit.win_move(self.title, x, y, width, height, text=self.text)         

    def setState(self, flag):
        '''
        :description 显示,隐藏,最小化,最大化或还原一个窗口.
        :param flag: The "show" flag of the executed program:
                    1 = 显示
                    2 = 最小化/隐藏
                    3 = 最大化
                    4 = 还原
        :return 1:成功, 0:失败(窗口不存在).
        '''
        return autoit.win_set_state(self.title, flag, text=self.text)

    def wait(self, timeout=5):
        '''
        :description 暂停脚本的执行直至指定窗口存在(出现)为止.
        timeout 单位为秒.
        :return PID:成功, 0:失败(超时).
        '''
        return autoit.win_wait(self.title, timeout, text=self.text)            

    def waitActive(self, timeout=5):
        '''
        :description 暂停脚本的执行直至指定窗口被激活(成为活动状态)为止.
        timeout 单位为秒.
        :return PID:成功, 0:失败(超时).
        '''
        return autoit.win_wait_active(self.title, timeout, text=self.text)         

    def waitClose(self, timeout=5):
        '''
        :description 暂停脚本的执行直至所指定窗口不再存在为止.
        timeout 单位为秒.
        :return 1:成功, 0:失败(超时).
        '''
        return autoit.win_wait_close(self.title, timeout, text=self.text)        

    def waitNotActive(self, timeout=5):
        '''
        :description 暂停脚本的执行直至指定窗口不是激活状态为止.
        timeout 单位为秒.
        :return 1:成功, 0:失败(超时).
        '''
        return autoit.win_wait_not_active(self.title, timeout, text=self.text)              

    def controlClick(self, control, button="main", clicks=1):
        '''
        :description 向指定控件发送鼠标点击命令.
        '''
        autoit.control_click(self.title, control, text=self.text, button=button, clicks=clicks)

    def controlCommand(self, control, command, extra="", buf_size=256):
        '''
        :description 向指定控件发送命令.
        :param command, extra:                         :return
                    "IsVisible", ""                    1:可见; 0:不可见
                    "IsEnabled", ""                    1:可用; 0:禁用
                    "ShowDropDown", ""                弹出/下拉 组合框(ComboBox)的列表.
                    "HideDropDown", ""                收回/隐藏 组合框(ComboBox)的列表.
                    "AddString", "string"                在 ListBox 或 ComboBox 的编辑框后面附加指定字符串.
                    "DelString", 出现次序                                删除在 ListBox 或 ComboBox 的编辑框中指定的字符串(从0开始).
                    "FindString", "string"                返回在 ListBox 或 ComboBox 的编辑框中与指定字符串匹配项目的出现次序(从0开始).
                    "SetCurrentSelection", 出现次序            通过指定出现次序(从0开始)把 ListBox 或 ComboBox 的当前选择项设为指定的项目.
                    "SelectString","string"            通过指定字符串把 ListBox 或 ComboBox 的当前选择项设为匹配字符串的项目.
                    "IsChecked", ""                    若目标按钮(复选框/单选框)被选中则返回值为1,否则为0.
                    "Check", ""                        使目标按钮(复选框/单选框)变为选中状态.
                    "UnCheck", ""                        使目标按钮(复选框/单选框)变为非选中状态.
                    "GetCurrentLine", ""                    返回在目标编辑框中插入符(caret,光标)的所在行号.
                    "GetCurrentCol", ""                    返回在目标编辑框中插入符(caret,光标)的所在列号.
                    "GetCurrentSelection", ""                返回 ListBox 或 ComboBox 控件当前选中的项目名.
                    "GetLineCount", ""                        返回目标编辑框中的总行数.
                    "GetLine", 行号                                        返回目标编辑框中指定行的文本内容.
                    "GetSelected", ""                    返回目标编辑框中的(用户用鼠标或其它方式)选定的文本.
                    "EditPaste", 'string'                在目标编辑框中插入符(caret)所在位置后插入指定字符串.
                    "CurrentTab", ""                    返回在 SysTabControl32 控件中当前显示的标签编号(从1开始).
                    "TabRight", ""                        使 SysTabControl32 控件切换到(右边的)下一个标签.
                    "TabLeft", ""                        使 SysTabControl32 控件切换到(左边的)下一个标签. 
                    "SendCommandID", 命令 ID            模拟 WM_COMMAND 消息. 通常用于 ToolbarWindow32 控件 - 使用Au3Info的工具栏标签得到命令ID.
        '''        
        return autoit.control_command(self.title, control, command, buf_size, text=self.text, extra=extra)

    def controlListView(self, control, command, extra1, extra2="", buf_size=256):
        '''
        :description 向指定的 ListView32 控件发送命令.
        :param command, extra1, extra2:                         :return
                    "DeSelect", 从[, 到]                        取消选定从"从"开始直到"到"的一个或多个项目. 
                    "FindItem", "搜索字符串" [, 子项目]            返回与给定字符串匹配的项目的位置.若未找到指定字符串则返回值为 -1. 
                    "GetItemCount"                                返回列表中项目的数量. 
                    "GetSelected" [, 选项]                        返回当前选中项目的位置.若 选项=0(默认)则只返回选中的第一个项目;若 选项=1 则返回由竖线"|"作为分隔符的所有选中项目,例如:"0|3|4|10".若没有选中任何项目则返回一个空字符串"". 
                    "GetSelectedCount"                            返回选中项目的数量. 
                    "GetSubItemCount"                            返回子项目的数量. 
                    "GetText", 项目, 子项目                                            返回指定项目/子项目的文本. 
                    "IsSelected", 项目                                                    若指定项目被选中则返回值为1,否则返回值为0. 
                    "Select", 从[, 到]                            选中一个或多个项目(请参考第一个命令). 
                    "SelectAll"                                    选中所有项目. 
                    "SelectClear"                                取消所有项目的选中状态. 
                    "SelectInvert"                                切换当前的选中状态. 
                    "ViewChange", "视图"                        切换当前的视图.可用的视图包括"list"(列表),"details"(详细信息),"smallicons"(小图标),"largeicons"(大图标). 
        '''        
        return autoit.control_list_view(self.title, control, command, buf_size, text=self.text, extra1=extra1, extra2=extra2)        

    def controlDisable(self, control):
        '''
        :description 禁用或使某控件变成灰色不可用状态.
        :return 1:成功; 0:失败.
        '''        
        return autoit.control_disable(self.title, control, text=self.text)

    def controlEnable(self, control):
        '''
        :description 使灰色按钮/控件变为"可用"状态.
        :return 1:成功; 0:失败.
        '''        
        return autoit.control_enable(self.title, control, text=self.text)        

    def controlFocus(self, control):
        '''
        :description 设置输入焦点到指定窗口的某个控件上.
        :return 1:成功; 0:失败.
        '''        
        return autoit.control_focus(self.title, control, text=self.text)  

    def controlGetText(self, control):
        '''
        :description 获取指定控件上的文本.
        :return 文本内容:成功; 空:失败.
        '''        
        return autoit.control_get_text(self.title, control, text=self.text)   

    def controlSend(self, control, send_text, mode=0 ):    
        '''
        :description 向指定的控件发送字符串.
        :param mode: 0:按特殊字符含义发送(默认); 1:原样发送.
        :return 1:成功; 0:失败(窗口/控件未找到).
        '''        
        return autoit.control_send(self.title, control, send_text, mode, text=self.text)   

    def controlSetText(self, control, control_text):
        '''
        :description 修改指定控件的文本.
        :return 1:成功; 0:失败(窗口/控件未找到).
        '''        
        return autoit.control_set_text(self.title, control, control_text, text=self.text)   

    def controlTreeView(self, control, command, extra, buf_size=256):
        '''
        :description 发送一个命令到 TreeView32 控件.(子节点不好用*)
        :param command, extra                             :return
        "Check", "项目"                                             选中一个项目 (如果项目支持选中,这里指项目带有选择框). 
        "Collapse", "项目"                                          折叠一个项目节点,使它隐藏它的子项目. 
        "Exists", "项目"         *都返回1*                      如果项目存在返回 1,否则返回 0. 
        "Expand", "项目"                                           展开一个项目节点,使它显示它的子项目. 
        "GetItemCount", "项目"                                 返回所选项目的子项目数量. 
        "GetSelected" [, 使用索引]                             返回当前所选项目的文本参考信息(如果使用索引设置为1将会返回所选项目索引位置). 
        "GetText", "项目"                                          返回项目文本. 
        "IsChecked"                                                  返回项目选中状态. 1:被选中, 0:未被选中, -1:没要选择框. 
        "Select", "项目"                                             选择一个项目. 
        "Uncheck", "项目"                                         取消项目选中状态 (如果项目支持选中,这里指项目带有选择框). 
        '''        
        return autoit.control_tree_view(self.title, control, command, text=self.text, buf_size=buf_size, extra=extra)          

    def statusbarGetText(self, part=1, buf_size=256):
        '''
        :description 获取标准状态栏控件的文本.
        :return 文本内容:成功; 空字符串:失败(无法读取文本).
        '''        
        return autoit.statusbar_get_text(self.title, self.text, part, buf_size)

基础用法

字符串处理

去空格
python
lstrip 去掉左边的空格
>>>a=" gho stwwl "
>>>a.lstrip()
'gho stwwl '

rstrip 去掉右边的空格
>>>a.rstrip()
' gho stwwl'

strip 同时去掉左右两边的空格
>>>a.strip()
'gho stwwl'

md5

python
from hashlib import md5


def encode(tmp,md5_key):
  key = tmp+md5_key
  return md5(key.encode("utf-8")).hexdigest()

print(encode("12312",'ctu800617'))

pymouse

image-20210201162530623

数据类型

字节与字符串的转换

字符串转字节
python
"abc".encode()

bytes,encode默认编码方式是utf-8

字节转字符串
python
b"abc".decode()

string,encode默认编码方式是utf-8

bytes类型的unicode(中文)输出
python
s = '\\u4eca\\u5929\\u5929\\u6c14\\u4e0d\\u9519'        #中文是:今天天气真不错
new_s = s.encode().decode('unicode_escape')        #输出为:今天天气真不错

word转换成图片

python
#coding:utf-8
from docx.shared import Cm
from docx import Document   #用来建立一个word对象
from docx.shared import Pt  #用来设置字体的大小
from docx.shared import Inches
from docx.oxml.ns import qn  #设置字体
from docx.shared import RGBColor  #设置字体的颜色
from docx.enum.text import WD_ALIGN_PARAGRAPH  #设置对其方式
import re

# pip  install python-docx
# Word中的
# 字号五号对应磅值10.5,
# 字号小四对应磅值12,
# 字号四号对应磅值14,
# 字号小三对应磅值15,
# 字号三号对应磅值16,
# 字号小二对应磅值18,
# 字号二号对应磅值22,
# 字号小一对应磅值24,
# 字号一号对应磅值26,
# 字号小初对应磅值36
def modify_docx(input_docx,output_docx,product_name):
    document=Document(input_docx)
    # 首先对段落格式进行修改,docx默认标题也属于段落,因此“表扬信”是第一段
    paragraphs=document.paragraphs
    # paragraphs[2].paragraph_format.first_line_indent=Cm(0.74)
    # paragraphs[3].paragraph_format.left_indent=Cm(0.74)
    # paragraphs[4].paragraph_format.alignment=WD_ALIGN_PARAGRAPH.RIGHT
    # paragraphs[4].paragraph_format.right_indent=Cm(2)
    # paragraphs[5].paragraph_format.alignment=WD_ALIGN_PARAGRAPH.RIGHT
    # paragraphs[5].paragraph_format.right_indent=Cm(2)

    document.styles["Normal"].font.name=u"宋体"  #设置全局字体
    document.styles["Normal"]._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
    document.styles["Normal"].font.color.rgb=RGBColor(0,0,0)#设置正文全局颜色为黑色
    document.styles["Normal"].font.size=Pt(14)#设置正文全局大小为29
    # document.styles["Heading 2"].font.size=Pt(29)#设置全局2级标题的字体大小为29
    # for line in paragraphs:
    #     print(line.text)
    print(paragraphs[3].text)
    # 对文本进行修改
    # 修改第二段
    # paragraphs[1].text="小Z同学:"
    # # 将第三段陆亦可替换为大Z,她替换为他。通过python的正则表达式,可以很简单地实现文本的替换和查找。
    text=re.sub('畅天游vr产品201',product_name,paragraphs[3].text)
    # text=re.sub('她','他',text)
    # 样式
    # style = paragraphs[3].style
    paragraphs[3].text=''
    run = paragraphs[3].add_run()
    run.text = product_name
    run.font.underline = True

    run = paragraphs[3].add_run()
    run.text = " (作品名称)由 "

    run = paragraphs[3].add_run()
    run.text = "北京畅天游科技有限公司"
    run.font.underline = True

    run = paragraphs[3].add_run()
    run.text = " (单位名称)内部员工共同完成,代表法人意志,是法人作品。"

    run = paragraphs[3].add_run()
    run.text = "北京畅天游科技有限公司"
    run.font.underline = True

    run = paragraphs[3].add_run()
    run.text = "  对此作品承担一切法律责任, "

    run = paragraphs[3].add_run()
    run.text = product_name
    run.font.underline = True

    run = paragraphs[3].add_run()
    run.text = " 的全部著作权归  "

    run = paragraphs[3].add_run()
    run.text = "北京畅天游科技有限公司"
    run.font.underline = True

    run = paragraphs[3].add_run()
    run.text = "  所有。"

    # run.font.underline = True
    # 畅天游vr产品201 (作品名称)由 北京畅天游科技有限公司 (单位名称)内部员工共同完成,代表法人意志,是法人作品。北京畅天游科技有限公司
    # 对此作品承担一切法律责任, 畅天游vr产品201 的全部著作权归 北京畅天游科技有限公司 所有
    # paragraphs[3].style = style
    # # 在第四段后面加上
    # paragraphs[3].add_run("向小z同学学习!")
    # # 修改表格里面的内容
    # tables=document.tables
    # tables[0].cell(1,0).text="猫粮"
    # tables[0].cell(2,0).text="猫粮"
    # tables[0].cell(3,0).text="猫粮"
    # # 插入一张图片,图片宽度设置为11.8cm
    # document.add_picture('fun.jpg', width=Cm(11.8))
    document.save("./test.docx")
# modify_docx(r"./法人作品权利归属声明.docx","./test.docx",'畅天游vr产品203')

import subprocess
from subprocess import Popen, PIPE


def word_to_pdf(outfile, infile, timeout=None):
    """将word 转换为pdf
    函数说明:将路径为infile的word文件转换为pdf,保存进路径为outfile的pdf文件.
    参数: outfile(str):保存文件pdf 的路径.
    参数: infile(str):word文件的路径.
    参数: timeout:转换文件时的时间延迟.
    """
    args = ['libreoffice', '--headless', '--convert-to', 'pdf', '--outdir', outfile, infile]
    process = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout)
    re.search('-> (.*?) using filter', process.stdout.decode())
word_to_pdf("./test.pdf","test.docx")

sikuli

参考资料

下载: https://raiman.github.io/SikuliX1/downloads.html

Quickstart: http://www.sikulix.com/quickstart/#qs2

sikulixpai: https://launchpad.net/sikuli/sikulix/2.0.4/+download/sikulixapi-2.0.4.jar

sikulixapi源码: https://repo1.maven.org/maven2/com/sikulix/sikulixapi/2.0.4/sikulixapi-2.0.4-sources.jar

使用方法

启动
java -jar path-to/sikulix.jar

If you have any problems, run this from a commandline and analyse the log output

java -jar path-to/sikulix.jar -v -c

常用工具函数

遍历文件夹
python
for root, root_dir, files in os.walk(root_path):
  for filename in files:
    file_path = os.path.sep.join([root, filename])
    if not os.path.exists(file_path):
      print("无效证书(exists)",file_path)
按行读取文件
python
with open("data.txt",'r') as file:
    for line in file.readlines():
        print (''''%s','''%line)
写文本日志
python
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.info("hello")
方法2

logger.json

json
{
    "version":1,
    "disable_existing_loggers":false,
    "formatters":{
        "simple":{
            "format":"%(asctime)s - %(threadName)s - %(levelname)s - %(message)s",
            "datefmt":"%Y-%m-%d %H:%M:%S"
        }
    },
    "handlers":{
        "console":{
            "class":"logging.StreamHandler",
            "level":"DEBUG",
            "formatter":"simple",
            "stream":"ext://sys.stdout"
        },
        "info_file_handler":{
            "class":"logging.handlers.TimedRotatingFileHandler",
            "level":"INFO",
            "formatter":"simple",
            "filename":"./logs/info.log",
            "when":"D",
            "interval":1,
            "backupCount":7,
            "encoding":"utf8"
        },
        "error_file_handler":{
            "class":"logging.handlers.TimedRotatingFileHandler",
            "level":"ERROR",
            "formatter":"simple",
            "filename":"./logs/errors.log",
            "when":"D",
            "interval":1,
            "backupCount":7,
            "encoding":"utf8"
        }
    },
    "loggers":{
        "module1":{
            "level":"ERROR",
            "handlers":[
                "console"
            ],
            "propagate":"no"
        }
    },
    "root":{
        "level":"INFO",
        "handlers":[
            "console",
            "info_file_handler",
            "error_file_handler"
        ]
    }
}
python
import os
import logging.config
import json

class LogUtil:
    #创建一个字典,用户保存配置
    dictConf = {}
    # 配置文件的目录
    LOGGER_CONF_PATH = '../'
    # 配置文件的名称
    LOGGER_CONF_NAME = 'logger.json'
    #构造方法
    def __init__(self,app_name="app_name",eid="eid",dir="./logs"):
        logJsonPath = self.LOGGER_CONF_PATH + os.sep + self.LOGGER_CONF_NAME
        self.dictConf = json.load(open(logJsonPath, 'r',encoding="utf-8"))
        if not os.path.exists(dir):
            os.makedirs(dir)
    #模块名
    LOGGER_NAME = 'runLogger'
    def getLogger(self,loggerName = LOGGER_NAME):
        logging.config.dictConfig(config=self.dictConf)
        logger = logging.getLogger(loggerName)
        return logger

    def info(self,*msg):
        self.getLogger().info(str(msg))

    def error(self,*msg):
        self.getLogger().error(str(msg))

    def warn(self,*msg):
        self.getLogger().warning(str(msg))

读写pdf

读pdf
python
filepath = 'xxx.pdf'
import pdfplumber

def read_pdf(pdf_path):
    with pdfplumber.open(pdf_path) as pdf:
        first_page = pdf.pages[0]  # 获取第一页
        text = []
        for charItem in first_page.chars:
            text.append(charItem['text'])
        return "".join(text)

print(read_pdf(filepath))

读写CSV

python
import csv
import os
class CSVHelper:
    def __init__(self,filepath):
        self.file = []
        self.filepath = filepath

    def save_data(self, item_id,values):
        if self.is_exists(item_id):
            return False
        with open(self.filepath, mode='a') as f2:
            cw = csv.writer(f2)
            # 采用writerow()方法
            cw.writerow([values])
            return True

    # 是否有id
    def is_exists(self, item_id):
        if not os.path.exists(self.filepath):
            return False
        with open(self.filepath, 'r') as f:
            cr = csv.reader(f)
            for row in cr:
                if row.__sizeof__() <= 0:
                    continue
                if len(row) == 0:
                    continue
                if row[0].find(item_id) >= 0:
                    return True
            return False

    def read_data(self):
        data = []
        with open(self.filepath, 'r') as f:
            cr = csv.reader(f)
            for row in cr:
                data.append(row[0].split(","))
        return data
python
if __name__ == '__main__':
    csv_helper = CSVHelper("upload_list.csv")
    # csv_helper.save_data("100",'100,作品名称,照片名称,拍摄时间,照片路径')
    for item in csv_helper.read_data():
        print(item)

win32gui

参考资料

https://www.programcreek.com/python/index/322/win32gui

http请求

python
import requests

# get请求 
def http_get(url):
    try:
        res = requests.request("GET",url)
        res = res.json()
        return res['data'][0]['createTime'].split(" ")[0].replace("-","/")
    except Exception as ex:
        print(ex)
        return

    def post(self,url,body):
        print(url)
        print(body)
        headers = {
            "content-type":"application/json"
        }
        res =  requests.post(url,body,headers=headers).json()
        logger.info(res)
        return res

# post 请求
def http_post(self,url,body):
    print(url)
    print(body)
    headers = {
        "content-type":"application/json"
    }
    res =  requests.post(url,body,headers=headers).json()
    logger.info(res)
    return res

pyautogui

特点

不支持多个窗口,即使是远程桌面

安装方法

bash
pip install pyautogui
python
import pyautogui
pyautogui.position()
pyautogui.size()
pyautogui.onScreen(100,100)

获取截屏

https://www.jb51.net/article/168609.htm

测试路径

http://192.168.3.36:8888/notebooks/Desktop/测试后台按键精灵.ipynb

图片处理

压缩图片

python
from PIL import Image, ImageDraw, ImageFont

# 压缩图片
def compress_image(src_path,dest_path,way=1, compress_rate=0.5, show=False):
    '''
    img.resize() 方法可以缩小可以放大
    img.thumbnail() 方法只能缩小
    :param way:
    :param compress_rate:
    :param show:
    :return:
    '''
    img = Image.open(src_path)
    w, h = img.size
    img_name = src_path.split('/')[-1]
    # 方法一:使用resize改变图片分辨率,但是图片内容并不丢失,不是裁剪
    if way == 1:
        img_resize = img.resize((int(w * compress_rate), int(h * compress_rate)))
        resize_w, resieze_h = img_resize.size
        img_resize.save(dest_path)
        if show:
            img_resize.show()  # 在照片应用中打开图片
            # 或
            # plt.imshow(img_resize)
            # plt.axis('off')
            # plt.show()

    # 方法二: 和resize方法类似,不过这里我测试好型这个函数已经不能使用,不知是不是版本问题
    # 问题:https://blog.csdn.net/kethur/article/details/79992539  tumbnail没有返回值
    if way == 2:
        # img_resize = img.thumbnail((400, 400))
        img.thumbnail((int(w * compress_rate), int(h * compress_rate)))
        resize_w, resize_h = img.size
        img.save(dest_path)
    print("%s 已压缩," % (img_name), "压缩率:", compress_rate)

if __name__ == '__main__':
    compress_image('/Users/wangxiaomin/Desktop/poi-marker-red.png',
                   '/Users/wangxiaomin/Desktop/poi-marker-red2.png',way=2)

生成水印

python
def generate_watermark(src_path,dest_path,text,font_path):
    src = Image.open(src_path)
    w, h = src.size
    img = src.copy()
    draw = ImageDraw.Draw(img)
    fnt = ImageFont.truetype(font_path, 100)
    line = "作品名称: "+text
    start_x = w/9*1
    start_y = h/6*5-300
    split = 120
    draw.text((start_x, start_y), line, (0, 0, 0),font=fnt)
    line = "作者: 北京畅天游科技有限公司"
    draw.text((start_x, start_y+split*1), line, (0, 0, 0), font=fnt)
    line = "著作权人: 北京畅天游科技有限公司"
    draw.text((start_x, start_y+split*2), line, (0, 0, 0), font=fnt)
    img.save(dest_path)

# generate_watermark("/Volumes/PATRICK/ctu/ctu_robot/src/vr-right/dest/473_834622.jpg",
#                        "/Volumes/PATRICK/ctu/ctu_robot/src/vr-right/dest/473_834622-1.jpg","合宿·8号院vr产品1","/System/Library/Fonts/PingFang.ttc")

按键精灵

大漠插件

https://github.com/AmosLee95/yys-bot

pandoc

生成pdf

参考资料

https://zhuanlan.zhihu.com/p/146141170

Git: https://github.com/jgm/pandoc/releases/tag/2.2.1

wxpython

参考资料

内嵌浏览器 https://www.cnblogs.com/abcyrf/p/10031047.html