快乐学习
前程无忧、中华英才非你莫属!

python通过模版生成发票

zhangtongle阅读(412)

要使用Jinja2模板引擎生成个性化文档并自动保存为PDF格式,你可以按照以下步骤进行:

1. 安装所需库

首先,确保安装了必要的库,包括 Jinja2WeasyPrint(用于生成PDF)。

pip install Jinja2 WeasyPrint

2. 创建模板文件

在项目目录下创建一个模板文件,例如 invoice_template.html。这个文件将包含HTML格式的文档结构。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>发票</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .invoice { margin: 20px; }
    </style>
</head>
<body>
    <div class="invoice">
        <h1>发票</h1>
        <p>客户姓名: {{ customer_name }}</p>
        <p>发票日期: {{ invoice_date }}</p>
        <p>金额: {{ amount }} 元</p>
        <p>描述: {{ description }}</p>
    </div>
</body>
</html>

3. 编写生成文档的脚本

创建一个Python脚本来处理用户输入数据,生成文档并保存为PDF。

from jinja2 import Environment, FileSystemLoader
from weasyprint import HTML

def generate_invoice(data):
    # 设置Jinja2模板环境
    env = Environment(loader=FileSystemLoader('.'))
    template = env.get_template('invoice_template.html')

    # 渲染模板
    rendered_html = template.render(data)

    # 保存为PDF
    HTML(string=rendered_html).write_pdf('invoice.pdf')

if __name__ == "__main__":
    # 示例用户输入数据
    invoice_data = {
        'customer_name': '张三',
        'invoice_date': '2024-09-20',
        'amount': '1000',
        'description': '服务费用'
    }

    generate_invoice(invoice_data)

4. 运行脚本

运行上述Python脚本,生成的PDF文件将保存在当前目录下,命名为 invoice.pdf

5. 自定义和扩展

你可以根据需要修改模板和数据结构,支持更多个性化信息,比如添加图标、公司名称、条款等内容。

这样,你就可以根据用户输入生成个性化的文档并保存为PDF格式。需要更多功能或其他问题,随时告诉我!

定时增量备份mysql 数据库

zhangtongle阅读(396)

好的,以下是一个使用 Python 实现 MySQL 数据库每日定时增量备份的示例。我们将使用 schedule 库定时任务,并利用 MySQL 的二进制日志(binary log)功能进行增量备份。

步骤概述

  1. 设置 MySQL 二进制日志:确保 MySQL 配置了二进制日志功能。
  2. 编写备份脚本:使用 Python 进行增量备份。
  3. 定时任务:使用 schedule 库定时执行备份任务。

1. 设置 MySQL 二进制日志

确保在 MySQL 配置文件中(通常是 my.cnfmy.ini)启用二进制日志:

[mysqld]
log_bin=mysql-bin
expire_logs_days=7  # 保留日志的天数

重启 MySQL 服务以使配置生效。

2. 编写备份脚本

使用 mysql-connector-python 库连接数据库,并编写增量备份逻辑:

import mysql.connector
import subprocess
import schedule
import time
from datetime import datetime

# 数据库连接配置
db_config = {
    'user': 'your_username',
    'password': 'your_password',
    'host': 'localhost',
    'database': 'your_database',
}

# 增量备份函数
def incremental_backup():
    # 获取当前时间戳
    now = datetime.now().strftime('%Y%m%d_%H%M%S')
    backup_file = f'backup_{now}.sql'

    # 获取二进制日志文件名和位置
    conn = mysql.connector.connect(**db_config)
    cursor = conn.cursor()

    cursor.execute("SHOW MASTER STATUS;")
    log_file, log_pos = cursor.fetchone()[:2]

    # 生成增量备份命令
    dump_command = f"mysqldump --user={db_config['user']} --password={db_config['password']} " \
                   f"--host={db_config['host']} --single-transaction --flush-logs " \
                   f"--master-data=2 --databases {db_config['database']} " \
                   f"> {backup_file}"

    # 执行备份
    subprocess.run(dump_command, shell=True)

    # 记录日志
    with open("backup_log.txt", "a") as log_file:
        log_file.write(f"{now} - Incremental backup completed: {backup_file} " 
                       f"(Log File: {log_file}, Log Position: {log_pos})\n")

    cursor.close()
    conn.close()

# 定时任务
schedule.every().day.at("02:00").do(incremental_backup)  # 每天凌晨2点执行

# 主循环
while True:
    schedule.run_pending()
    time.sleep(60)  # 等待1分钟

3. 运行脚本

确保安装了所需的库:

pip install mysql-connector-python schedule

然后运行脚本。它会在每天的指定时间执行增量备份。

注意事项

  1. 性能影响:使用 --single-transaction 可以减少备份对数据库性能的影响。
  2. 权限:确保数据库用户具有相应的权限进行备份。
  3. 备份管理:定期清理旧的备份文件,以节省存储空间。

注意:以上来自于ChatGPt ,还没有进行测试,只是提供思路,谢谢~

Python批量读取身份证信息录入系统和重命名

zhangtongle阅读(500)

前言

大家好,

如果你对自动化处理身份证图片感兴趣,可以尝试以下操作:从身份证图片中快速提取信息,填入表格并提交到网页系统。如果你无法完成这个任务,我们将在“Python自动化办公2.0”课程中详细讲解实现整个过程。

实现过程概述:
模块与功能:

re 模块:用于从 OCR 识别出的文本中提取所需的信息。
日期模块:计算年龄。
pandas:处理和操作表格数据。
PaddleOCR:百度的 OCR 模块,适合中文文本识别。
concurrent.futures:实现并发处理,提高图片识别效率。请注意,CPU 性能较弱时,过多的并发可能导致识别不准确。
SimpleAutomation:封装了 Selenium 操作网页的功能,也可以直接使用 Selenium 实现网页自动化。
装饰器使用:

我们使用装饰器来分离代码逻辑,使代码更加清晰。装饰器可以用于日志记录、异常处理和函数计时等公共功能的重用。
过程安排:

批量处理:我们批量处理身份证图片,通过并发操作加快处理速度。
信息提取:利用 OCR 技术识别身份证中的文本信息,并使用正则表达式提取所需字段。
数据处理:使用 pandas 将提取的信息整理成表格。
信息提交:将处理后的数据填写到网页表单中,并提交。
这个过程涉及多个步骤和技术,代码需要经常编写和调试,以提高编程能

实现最终结果

需要把下面三张身份证,识别的文字,填入到对应下面的Excel 报表中。
并通过https://www.ztloo.com/profile__trashed/card/ 身份证录入页面,进行web自动化填入。

1. 导入所需库

logging: 标准库日志模块,用于记录日志信息。
os: 提供操作系统接口,主要用于文件路径操作。
re: 提供正则表达式支持,用于从文本中提取信息。
shutil: 提供高级文件操作功能,例如文件复制。
time: 提供时间相关功能,如延时。
datetime: 提供日期和时间处理功能。
loguru: 现代化的日志库,用于记录日志信息。
pandas: 提供数据结构和数据分析工具,用于处理和分析数据。
paddleocr: OCR 工具,用于文本识别。
concurrent.futures: 提供并发执行任务的功能。

2. 配置日志记录

设置了日志文件 ocr_task.log,并关闭了 PaddleOCR 的日志输出,以减少冗余日志信息。

3. OCRProcessor 类

3.1 初始化

init: 初始化 PaddleOCR 引擎和数据列表。

3.2 识别文本

recognize_text: 使用 PaddleOCR 对图片进行文本识别,返回识别的文本。

3.3 提取信息

extract_info: 使用正则表达式从识别的文本中提取身份证相关信息,包括姓名、性别、民族、出生日期、住址和身份证号码。

3.4 列出图片

list_images: 列出指定目录中的所有图片文件,支持 .png、.jpg、.jpeg 格式。

3.5 处理图片

process_img: 处理单张图片,进行 OCR 识别,提取信息并将结果记录到 self.data 列表中。

3.6 处理图片目录

process_imgs: 并行处理目录中的所有图片,使用 ThreadPoolExecutor 执行任务,并将处理结果保存在 ocr_results.xlsx 文件中。调用了 add_age_and_sort 方法对数据进行排序和添加年龄列。

3.7 计算年龄

calculate_age: 根据出生日期计算年龄。

3.8 添加年龄并排序

add_age_and_sort: 为数据添加年龄列,并按年龄从小到大排序。使用 pandas 处理数据。

3.9 重命名并保存图片

rename_and_save_images: 根据提取的身份证信息重命名图片,并保存到指定目录中。

3.10 处理和提交

process_and_submit: 执行完整的处理流程,包括初始化自动化工具、批量处理图片、重命名图片、提交信息到系统。使用 SimpleAutomation 进行网页操作,填写身份证系统表单。

3.11 提交信息到系统

write_idcard_system: 将提取的信息填写到身份证系统的表单中,包括姓名、性别、出生日期、地址、身份证号码。选择性别和民族选项,提交表单。

4. 使用示例

main 部分,创建了 OCRProcessor 实例,并调用 process_and_submit 方法处理指定目录下的图片并提交信息到系统。

Pytest全栈自动化测试指南-课程声明!

zhangtongle阅读(1127)

尊敬的用户,

近期我们发现有部分用户从非官方渠道购买了盗版课程内容。这不仅损害了我们的合法权益,也影响了您自身的学习体验。

购买正版课程,您将获得:

  • 完整、高清的课程视频
  • 持续更新的学习资料
  • 专业的技术支持与答疑服务
  • 独家的学习社区交流机会

盗版课程不仅违法,且可能存在内容缺失、质量不佳等问题,严重影响您的学习效果。我们呼吁所有用户尊重知识产权,支持正版,共同营造一个健康、有序的学习环境。

Pytest全栈自动化测试指南正版官方发布渠道:

从其它渠道购买的,均属于翻录盗版,严重侵害了原创作者和其他购买课程用户的权益。

为了防止盗版,我们正积极联合平台的法务部门和国家版权局进行维权,追回部分损失,并希望让盗版者受到应有的法律制裁。

为了保护原价购买课程的用户,我们将对课程进行高质量的更新,提供更完善的资料和更优质的服务,彰显课程的真正价值。支持原创,从我们做起,每个订单的支持,都会让作者更有动力去创作更多优质内容。

考虑到部分用户可能经济困难,我们将为特别困难的小伙伴提供5折甚至1折优惠券。

如果您希望获得这些优惠券,我们需要您付出一些简单的劳动,比如在朋友圈多次分享我们的课程。我们将提供宣传软文,帮助您进行简单的广告宣传,时间为期2至3天。通过简单的劳动来获取知识。

1折优惠券仅针对特别困难且对知识有渴望的用户。我们希望您能尊重知识版权,尊重作者的劳动成果,并愿意付出一些劳动来获取知识。

感谢您的理解与支持。

Python3.11下载安装与创建独立虚拟环境

zhangtongle阅读(3613)

一、python 下载安装

1.去https://www.python.org 官网,按照图示点击下载Python3.11.4

2. 双击下载好的安装包,按照图示选自定义安装路径,便于项目管理,并勾选添加环境变量复选框

备注:然后一路next就可以了,

3、快捷键win(窗口键)+ R 打开运行,并键入cmd

备注:ctrl+z 并回车就可以退出解释器。

4. 设置仓库地址
pip config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple


备注: 设置软件模块的仓库地址,让python的模块,从国内豆瓣源镜像仓库下载。这样就不会出现timeout超时异常,模块下载不下来等异常。

注意: 豆瓣镜像源近期失效了,请更换腾讯或者清华的镜像源,请参考文字描述,不要参考图片中。

二、python 设置虚拟环境

1. 安装虚拟环境管理模块

pip install virtualenv
pip install virtualenvwrapper-win

2. 设置虚拟环境的系统环境变量

WORKON_HOME :D:\PyJob\virtualenv

D:\PyJob\virtualenv 这个路径要提前创建好,在PyJob文件夹下创建virtualenv 文件夹,用来存储各种独立的虚拟环境。防止冲突。

在Windows 10中,可以通过以下步骤快速打开系统环境变量:

1. 使用键盘快捷键 Win + X
2. 在弹出的菜单中,选择“系统”。
3. 在系统菜单中,点击“高级系统设置”。
4. 在弹出的对话框中,点击“环境变量”按钮。
5. 这将打开“环境变量”对话框,其中包含系统环境变量和用户环境变量的设置。

通过以上步骤,您可以快速打开系统环境变量并进行相应的设置。

3. 虚拟环境创建和管理

 mkvirtualenv -p D:\PyJob\py311\python.exe chatgpt  # 创建名字叫chatgpt的独立虚拟环境
 workon # 查看所有虚拟环境
 workon chatgpt # 进入和切换到chatgpt环境


备注:这样做的好处是,后期多个项目时,项目与项目之间不冲突,项目依赖的资源相互独立。

指定解释器,则使用
mkvirtualenv --python=python3安装路径 ztloo

包含系统解释器中已经安装的python包
mkvirtualenv test1 --system-site-packages(默认不包含系统环境中的python包)

删除独立虚拟环境
rmvirtualenv test1

如何与ChatGPT交流?ChatCatsy AI工具让你的对话更加智能!

zhangtongle阅读(3039)

📌 免责声明:本软件仅供学习测试使用,请勿使用本软件从事违法活动,否则一经发现,后果自负,将配合相关部门严厉打击。

本AI工具软件是基于ChatGPT技术研发而成,旨在提供更便捷、更智能的聊天体验。但请注意,该软件仅作为一种辅助工具,不能代替人类的判断和决策,也不能保证100%准确性和完整性。因此,使用本聊天软件所产生的任何结果和后果,本人不承担任何法律责任。用户需自行承担使用该软件的全部风险和责任,并且应该在使用前仔细阅读软件说明和功能介绍,了解其局限性和适用范围。最后,我们保留对免责声明的解释权和修改权,并且不对因软件使用导致的任何损失或损害承担法律责任。

第一章:软件介绍

🧑🏼‍🎨
ChatCatsy是一款完全由Python开发的桌面端软件,它可以与ChatGPT进行流畅的交流,并且具有类似Siri的语音交互功能。
只需说出“你好”,就能唤醒它。此外,ChatCatsy还包含了文字转换语音、生成字幕、音频功能以及音频转文字等多种实用功能。

为了满足用户的不同需求,ChatCatsy还提供了详细的设置功能,用户可以控制ChatGPT的版本模型、回答长度、随机性以及问答模式,包括官方API直连、记忆直连和记忆代理等多种模式。
此外,用户还可以对软件的外观进行设置,包括背景图、主题色和软件透明度等。

总之,ChatCatsy是一款功能强大、操作简便、界面美观的AI工具,可以帮助用户更加高效地进行文字和语音交流。如果你需要更多信息或者有任何疑问,请随时联系我们。我们非常期待与您合作,让ChatCatsy成为您的得力助手。

📌 说明:目前软件只支持Windows 版本,因为开发小哥手里暂时没有Mac电脑。当有些开发经费后,很快就能支持Mac 版本,敬请期待。


第二章:软件基本使用

🔑 step1: 获取官方网盘下载链接:

链接:https://pan.baidu.com/s/1Kk94l_X_weoQNli22S_MZg?pwd=abcd
提取码:abcd


🔑 step2: 把软件下载后,放在不含中文的文件夹里面。此软件是免安装的,双击即可使用。

🤖 软件版本区别:

ChatCatsyV1.0 : 内部不包含代理模式,需要自行连通国际互联网,并设为全局模式,才能使用内部功能。

ChatCatsyV1.1:内包含代理模式,不用连通国际互联网,便能使用软件内部问答模式,文字转语音。

注意:ChatCatsyV1.1 在V1.0的基础上,多了代理模式,如果在V1.1 使用内置代理模式,会导致语音转文字功能异常,因代理服务器暂时未支持语音转文字接口。如果想使用音频转文字功能,请联通国际互联网。


🔑 step3: 软件正版激活 打开软件后,如果是第一次使用,会弹窗激活对话框,要求使用者激活。对机器码右键copy 后,发送给开发小哥,小哥把对应的激活码发给你后,就可以的正常使用软件。一机对一码,把激活码保存好哟!


🔑 step4: 电脑网络设置为全局可连通国际互联网模式。(如果使用的ChatCatsyV1.1 版本,可以忽略此步骤。

🔑 step5: 设置API key


🔑 step6:验证软件服务是否正常

ChatCatsyV1.0 版本验证:(需要做step4步骤的操作)

ChatCatsyV1.1 版本验证:

第三章:软件定价

ChatCatsyV1.0 : 30元/个

ChatCatsyV1.1 : 50元/个

独立账号API秘钥 : 20元/个 (纯手工注册,数量有限!不单独供给!)

远程调试服务:20元/次

1级 2级 3级 4级 5级 6级 7级
正版软件 ChatCatsyV1.0 ChatCatsyV1.0 ChatCatsyV1.0 ChatCatsyV1.0 ChatCatsyV1.1 ChatCatsyV1.1 ChatCatsyV1.1
独立GPT账号
远程调试
价格 30 元 50元 50元 70元 50元 70元 90元

独立GPT账号-API秘钥 ,包含5美元额度,如何验证:

📌 注意1:全新的独立账号,额度剩余是5美元。

📌 注意2不要用共享账号,会面临随时封号和存在访问竞争,同一时间段,别人能用,你就用不了。隐私泄露!即使我们使用独立账号,提问数据也要不要涉及隐私信息,脱敏后进行知识的问答。

📌 注意3:当你的账号或秘钥,稳定使用后的某天,因不可抗力因素或因为多人使用你的账号,被openai官方封号, 损失自行承担。

📌 联系方式:开发小哥WeChat &qq : 1071235258

ChatGPT翩然起舞,以文本为笔创意无限

zhangtongle阅读(3309)

ChatGPT翩然起舞以文本为笔创意无限   原价198  重磅上新价:118.8
https://edu.51cto.com/course/33827.html

第一部分:ChatGPT基础

在这部分中,你将学习ChatGPT的基本概念和原理,了解自然语言处理的基本技术,以及如何使用ChatGPT进行对话和生成文本。

第二部分:ChatGPT prompts 提示词工程

这部分将教你如何构建有效的ChatGPT提示词,通过合理的提问和指导,引导ChatGPT生成你想要的回答和结果。

第三部分:ChatGPT高级应用

这部分将涵盖一系列高级应用,包括使用AI文本到图像生成器创造你想要的图像,语音处理技术,PPT制作工具,思维导图的制作方法以及视频制作的基本原理和工具。

第四部分:ChatGPT 开发框架和实用工具

在这部分中,你将学习ChatGPT的开发框架和常用实用工具,了解如何进行定制化开发和应用,以满足个人或企业的需求。

第五部分:ChatGPT在自动化办公中的应用

这部分将介绍如何将ChatGPT应用于自动化办公场景,例如自动回复邮件、智能日程安排、自动化报告生成等,提高工作效率和减轻重复性任务的负担。

第六部分:ChatGPT在商业应用中的应用

在这部分中,你将了解如何将ChatGPT应用于商业场景,包括市场调研、客户服务、智能推荐等领域,帮助企业提升竞争力和用户体验。

通过学习这门课程,你将掌握ChatGPT的基础知识和应用技巧,了解如何使用AI技术解决实际问题,并在自动化办公和商业应用中获得成长和优势。课程内容以图文结合的形式呈现,帮助你更好地理解和应用所学知识。

Pandas之read_excel函数的重要性

zhangtongle阅读(3233)

1、普通使用


excel_path = r'某公司销售数据-全国订单明细.xls' # Excel 数据路径
sales_data = pd.read_excel(excel_path) # 返回的DataFrame
sales_data.head(1) # 使用head 获取前1个数据

2、读取指定sheet

excel_sheet

pd.read_excel(excel_path,sheet_name='成绩表') # 读取成绩表

pd.read_excel(excel_path,sheet_name=2) # 读取全国订单明细,读取sheet的索引为2的表

3、指定表头

excel_header

把考勤表的第二行当表头

pd.read_excel(excel_path,sheet_name='考勤表',header=1)

4、只读取表中需要的列

# 通过列名
pd.read_excel(excel_path, usecols=['顾客姓名','订单数量','销售额'])[:2]
顾客姓名 订单数量 销售额
0 李鹏晨 6 261.54
1 王勇民 2 6.00
# 通过Excel 列的标识符。
pd.read_excel(excel_path, usecols="A:E")[:2]
订单号 订单日期 顾客姓名 订单等级 订单数量
0 3 2010-10-13 李鹏晨 低级 6
1 6 2012-02-20 王勇民 其它 2

5、将某列(字段)作为查询的的条件和依据)

# 将订单日期作为查询条件
df = pd.read_excel(excel_path,index_col=1,usecols="A:E")[:2]
df.loc['2011-07-15'] # 查询订单日期2011-07-15的所有数据
订单号 顾客姓名 订单等级 订单数量
订单日期
2011-07-15 32 姚文文 高级 26
2011-07-15 32 姚文文 高级 24

6、将多个字段作为查询条件

# 将订单日期和 订单等级作为查询索引(条件)
df = pd.read_excel(excel_path,index_col=[1,3],usecols="A:E")
df = df.sort_index()  # 需要将索引(查询字段)排序,要不不然会报警告

df.loc['2012-11-15','低级'].reset_index() # 查询日期和订单等级
订单日期 订单号 顾客姓名 订单数量
0 2012-11-15 13346 周雨生 44

7、跳过表中最后无用的数据

skip_footer

# 跳过工资表中的最后7行内容,不读取
pd.read_excel(excel_path,sheet_name='工资表',usecols="A:B",skipfooter=7)

8、指定Excel中的数据类型

# Excel 中salary数字列,夹杂了文字。需要转str,进一步的过滤和处理
df = pd.read_excel(excel_path,sheet_name='工资表',usecols="A:B",skipfooter=7, \
              dtype={'name': str, 'salary': str})

Python-导入模块的最佳实践

zhangtongle阅读(3477)

导入模块的“最佳实践”是什么

通常请勿使用 from modulename import * 。因为这会扰乱 importer 的命名空间,且会造成未定义名称更难以被 Linter 检查出来。

请在代码文件的首部就导入模块。这样代码所需的模块就一目了然了,也不用考虑模块名是否在作用域内的问题。每行导入一个模块则增删起来会比较容易,每行导入多个模块则更节省屏幕空间。

按如下顺序导入模块就是一种好做法:

standard library modules -- e.g. sys, os, argparse, re
third-party library modules (anything installed in Python's site-packages directory) -- e.g. dateutil, requests, PIL.Image
locally developed modules

为了避免循环导入引发的问题,有时需要将模块导入语句移入函数或类的内部。Gordon McMillan 的说法如下:

当两个模块都采用 "import " 的导入形式时,循环导入是没有问题的。
但如果第 2 个模块想从第 1 个模块中取出一个名称("from module import name")并且导入处于代码的最顶层,那导入就会失败。原因是第 1 个模块中的名称还不可用,这时第 1 个模块正忙于导入第 2 个模块呢。

如果只是在一个函数中用到第 2 个模块,那这时将导入语句移入该函数内部即可。当调用到导入语句时,第 1 个模块将已经完成初始化,第 2 个模块就可以进行导入了。

如果某些模块是平台相关的,可能还需要把导入语句移出最顶级代码。这种情况下,甚至有可能无法导入文件首部的所有模块。于是在对应的平台相关代码中导入正确的模块,就是一种不错的选择。

只有为了避免循环导入问题,或有必要减少模块初始化时间时,才把导入语句移入类似函数定义内部的局部作用域。如果根据程序的执行方式,许多导入操作不是必需的,那么这种技术尤其有用。如果模块仅在某个函数中用到,可能还要将导入操作移入该函数内部。请注意,因为模块有一次初始化过程,所以第一次加载模块的代价可能会比较高,但多次加载几乎没有什么花费,代价只是进行几次字典检索而已。即使模块名超出了作用域,模块在 sys.modules 中也是可用的只有为了避免循环导入问题,或有必要减少模块初始化时间时,才把导入语句移入类似函数定义内部的局部作用域。如果根据程序的执行方式,许多导入操作不是必需的,那么这种技术尤其有用。如果模块仅在某个函数中用到,可能还要将导入操作移入该函数内部。请注意,因为模块有一次初始化过程,所以第一次加载模块的代价可能会比较高,但多次加载几乎没有什么花费,代价只是进行几次字典检索而已。即使模块名超出了作用域,模块在 sys.modules 中也是可用的。

解决循环import的方法主要有几种:

1.延迟导入(lazy import)

  即把import语句写在方法或函数里面,将它的作用域限制在局部。
  这种方法的缺点就是会有性能问题。

2.将from xxx import yyy改成import xxx;xxx.yyy来访问的形式

3.组织代码

  出现循环import的问题往往意味着代码的布局有问题。
  可以合并或者分离竞争资源。
  合并的话就是都写到一个文件里面去。
  分离的话就是把需要import的资源提取到一个第三方文件去。
  总之就是将循环变成单向。

PyWin32系列文章-在过去8小时内发现的系统事件

zhangtongle阅读(3627)

Python对Eventlog的win32访问

如果您需要扫描许多服务器的事件日志或根据事件日志进行特定筛选,python的win32evtlogwin32evdlogutil库为您提供了一种有效的方法。

最重要的库是win32evtlog。使用它,您可以通过调用连接到服务器的事件日志。

实例
以下是基本调用:

logtype='System'
hand=win32evtlog.OpenEventLog(server,logtype)

这将返回一个句柄,您可以从该句柄进行调用,例如一个可以提供事件总数的句柄,或者另一个可以检查每个事件的详细信息的句柄。logtype变量设置为要查看的日志类型。默认值为:应用程序、安全性和系统。

掌握句柄后,您可以询问诸如记录数量或特定事件记录之类的信息:

total=win32evtlog.GetNumberOfEventLogRecords(hand)
flags = win32evtlog.EVENTLOG_BACKWARDS_READ|win32evtlog.EVENTLOG_SEQUENTIAL_READ
events=win32evtlog.ReadEventLog(hand,flags,0)

ReadEventLog返回一些事件对象,这些对象可能不是全部。您需要不断地检查循环,直到ReadEventLog不再返回事件。您可能注意到ReadEventLog有一个flags参数。标志(win32evtlog库中通常提供)指定如何读取事件日志。

下面是一个从ReadEventLog返回的事件中获取数据的简单循环:

for ev_obj in events:

    the_time=ev_obj.TimeGenerated.Format() #'12/23/99 15:54:09'

    evt_id=str(winerror.HRESULT_CODE(ev_obj.EventID))

    computer=str(ev_obj.ComputerName)

    cat=ev_obj.EventCategory

    seconds=date2sec(the_time)

    record=ev_obj.RecordNumber

    msg=str(win32evtlogutil.SafeFormatMessage(ev_obj, logtype))

    source=str(ev_obj.SourceName)

我们使用库win32evtlogutil获取事件的实际文本正文。要获取事件的易读日期,需要为事件对象的TimeGenerated部分指定“Format”方法。

win32evtlogutil可以方便地为我们提供事件日志消息的实际文本正文。如果您想根据关闭时间进行排序,这里有一个方便的函数,它使用python的time和regexp库将事件日志的时间格式转换为秒:

import re
import sys

import time
import traceback

import win32con
import win32evtlog
import win32evtlogutil
import winerror

def date2sec(evt_date):
    regexp = re.compile('(.*)\\s(.*)')  # store result in site
    reg_result = regexp.search(evt_date)
    time_res = reg_result.group() # 年月日时分秒
    res = time.strptime(time_res) # 由字符串转换成日期类型
    (mon, day, yr) = res.tm_mon,res.tm_mday,res.tm_year
    (hr, min, sec) = res.tm_hour,res.tm_min,res.tm_sec
    tup = yr, mon, day, hr, min, sec, 0, 0, 0
    sec = time.mktime(tup)
    return sec

flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ

# This dict converts the event type into a human readable form
evt_dict = {win32con.EVENTLOG_AUDIT_FAILURE: 'EVENTLOG_AUDIT_FAILURE',
            win32con.EVENTLOG_AUDIT_SUCCESS: 'EVENTLOG_AUDIT_SUCCESS',
            win32con.EVENTLOG_INFORMATION_TYPE: 'EVENTLOG_INFORMATION_TYPE',
            win32con.EVENTLOG_WARNING_TYPE: 'EVENTLOG_WARNING_TYPE',
            win32con.EVENTLOG_ERROR_TYPE: 'EVENTLOG_ERROR_TYPE'}

computer = 'localhost'  # 本地localhost
logtype = 'System'
begin_sec = time.time()
begin_time = time.strftime('%H:%M:%S  ', time.localtime(begin_sec))
# open event log
hand = win32evtlog.OpenEventLog(computer, logtype)
print(logtype, ' events found in the last 8 hours since:', begin_time)

try:
    events = 1
    while events:
        events = win32evtlog.ReadEventLog(hand, flags, 0)
        for ev_obj in events:
            # check if the event is recent enough
            # only want data from last 8hrs
            the_time = ev_obj.TimeGenerated.Format()
            seconds = date2sec(the_time)
            if seconds < begin_sec - 28800: break
            # data is recent enough, so print it out
            computer = str(ev_obj.ComputerName)
            cat = str(ev_obj.EventCategory)
            src = str(ev_obj.SourceName)
            record = str(ev_obj.RecordNumber)
            evt_id = str(winerror.HRESULT_CODE(ev_obj.EventID))
            evt_type = str(evt_dict[ev_obj.EventType])
            msg = str(win32evtlogutil.SafeFormatMessage(ev_obj, logtype))
            print(':'.join([the_time, computer, src, cat, record,evt_id, evt_type, msg[0:15]]))

        if seconds < begin_sec - 28800: break

    win32evtlog.CloseEventLog(hand)

except:
    print(traceback.print_exc(sys.exc_info()))
System  events found in the last 8 hours since: 23:19:40  
Fri Dec  2 23:18:03 2022:zhangtl:Microsoft-Windows-DNS-Client:0:186338:1014:EVENTLOG_WARNING_TYPE:在没有配置的 DNS 服务器响
Fri Dec  2 23:16:28 2022:zhangtl:DCOM:0:186337:10016:EVENTLOG_ERROR_TYPE:<The descriptio
Fri Dec  2 23:14:53 2022:zhangtl:Service Control Manager:0:186336:7036:EVENTLOG_INFORMATION_TYPE:Windows Error R
Fri Dec  2 23:12:53 2022:zhangtl:Service Control Manager:0:186335:7036:EVENTLOG_INFORMATION_TYPE:Windows Error R
Fri Dec  2 23:07:13 2022:zhangtl:Service Control Manager:0:186334:7040:EVENTLOG_INFORMATION_TYPE:Background Inte
Fri Dec  2 23:06:28 2022:zhangtl:DCOM:0:186333:10016:EVENTLOG_ERROR_TYPE:<The descriptio

特别的技术,给特别的你!

联系QQ:1071235258QQ群:710045715
error: Sorry,暂时内容不可复制!