躬行笔记 - Python
type: channel
link: https://www.fuzhoupyy.work/index.php/category/uncategorized/
items: 如何在 Azure 中创建 Windows 10 虚拟机
items: 通过命令行界面（winget）在 Windows 上安装 Node.js
items: 这个开源知识库太香了！PandaWiki搭建全过程，踩坑经验全分享
items: Python sh库：让运维脚本告别subprocess的痛苦，一行代码搞定系统命令
items: CDN优化实战：从命中率30%到95%的血泪史，AWS CloudFront踩坑全记录
items: 博客更新！！！
items: 云计算专业术语大揭秘！这些"黑话"你都懂吗？
items: python实现币安监控
items: 微信多开脚本
items: Python还能这么用？U盘加密工具保护你的秘密

如何在 Azure 中创建 Windows 10 虚拟机
type: item
date: 2025-11-12T15:07:00+00:00
description: 什么是虚拟机？虚拟机（VM）是由软件创建和运行的物理计算机的虚拟化版本。本质上，它就是一台“云端计算机”。创建步骤创建虚拟机：在 Azure 门户中搜索虚拟机。点击创建虚拟机，在下拉菜单中选择虚拟机。在“基本信息”选项卡上，选择现有资源组或为虚拟机创建一个新的资源组。为虚拟机创建一个实例名称。选择一个地区。如有必要，请选择可用区；否则，请选择“不需要基础架构冗余”。选择图像和兼容的安全类型“标准”。创建管理员帐户。选择用户名和密码。创建入站端口：HTTP (80) 和 RDP。确认资格。转到监控选项卡，禁用系统启动诊断。转到标签选项卡，为虚拟机创建一个标签。然后进行审核和创建。点击创建。部署完成后，转到资源，然后转到网络，增加虚拟机的屏幕使用时间。保存更改。进入虚拟机概览并连接虚拟机。请前往下载 RDP 文件。下载完成后，进入电脑的下载文件夹，通过远程桌面协议进行部署，然后输入你在管理员部分创建的密码。连接上创建的win10如果这篇文章对你有帮助，别忘了点赞转发支持一下！想了解更多运维实战经验和技术干货，记得关注微信公众号@运维躬行录，领取学习大礼包！！！我会持续分享更多接地气的运维知识和踩坑经验。让我们一起在运维这条路上互相学习，共同进步！公众号：运维躬行录个人博客：躬行笔记

通过命令行界面（winget）在 Windows 上安装 Node.js
type: item
date: 2025-11-08T14:19:02+00:00
description: 最近有接触到nodejs，今天就来讲讲在 Windows 上安装 Node.js ，直接通过命令行安装不再需要点击安装程序——这要归功于微软官方的 Windows 程序包管理器 winget 。以下是如何在几秒钟（三秒真男人！！！）内完全通过终端使用 npm 安装 Node.js 的方法。1. 打开 PowerShell按 Win + X → 选择 Windows PowerShell（管理员） 或终端（管理员） 。2. 查找可用的 Node.js 版本首先，列出所有可用的 Node.js 软件包：winget search OpenJS.NodeJS你会看到类似这样的结果：名称 ID 版本 源 ----------------------------------------------- Node.js OpenJS.NodeJS 25.1.0 winget Node.js 14 OpenJS.NodeJS.14 14.21.3 winget Node.js 16 OpenJS.NodeJS.16 16.20.2 winget Node.js 18 OpenJS.NodeJS.18 18.20.8 winget Node.js 20 OpenJS.NodeJS.20 20.19.5 winget Node.js 21 OpenJS.NodeJS.21 21.7.2 winget Node.js 22 OpenJS.NodeJS.22 22.21.0 winget Node.js 23 OpenJS.NodeJS.23 23.11.0 winget Node.js (LTS) OpenJS.NodeJS.LTS 24.11.0 winget选择 LTS 版本（推荐）或最新版本并安装：winget install -e --id OpenJS.NodeJS.LTS或者安装最新版本：winget install -e --id OpenJS.NodeJS⚠️ 建议大多数用户使用 LTS（长期支持）版本——它更稳定，并且会获得更长时间的安全更新。3. 重新打开命令行界面（重要！）安装完成后， 关闭并重新打开 PowerShell 或终端 。这将刷新 PATH 环境变量，以便识别 node 和 npm 。然后验证安装情况：node --version npm --version你应该能看到 Node.js 和 npm 的版本号（npm 与 Node.js 捆绑在一起）。4. 故障排除：PowerShell 中无法识别 npm。如果看到类似 npm : File C:\Program Files\nodejs\npm.ps1 cannot be loaded because running scripts is disabled on this system 的错误，则表示 PowerShell 的执行策略阻止了 npm 脚本。以下三种方法可以解决这个问题：选项 A：更改执行策略（推荐）以管理员身份运行 PowerShell 并设置执行策略：Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser然后关闭并重新打开 PowerShell。这样既可以运行本地脚本（例如 npm），又能防止未经签名的远程脚本运行。选项 B：改用命令提示符如果您不想更改 PowerShell 设置，请改用命令提示符 (cmd) 或带有命令提示符配置文件的 Windows 终端 。npm 在 cmd 中无需任何策略更改即可正常工作。选项 C：绕过当前会话暂时绕过当前 PowerShell 会话的策略：Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process这只会影响当前会话，关闭 PowerShell 时会重置。5.（可选）升级 npm保持 npm 更新：npm install -g npm@latest为什么要使用 winget？✅ 官方（由微软和 OpenJS 基金会维护）✅ 自动将 Node.js 和 npm 添加到 PATH 环境变量中（只需重新打开终端即可生效）✅ 完全可脚本化（非常适合自动化和持续集成）✅ 适用于全新机器的可复现设置就这样——你只需一条命令就在 Windows 上安装了 Node.js 和 npm，重新打开终端后即可使用。如果这篇文章对你有帮助，别忘了点赞转发支持一下！想了解更多运维实战经验和技术干货，记得关注微信公众号@运维躬行录，领取学习大礼包！！！我会持续分享更多接地气的运维知识和踩坑经验。让我们一起在运维这条路上互相学习，共同进步！公众号：运维躬行录个人博客：躬行笔记

这个开源知识库太香了！PandaWiki搭建全过程，踩坑经验全分享
type: item
date: 2025-10-23T14:40:42+00:00
description: 最近公司要搭建一个内部知识库，领导让我调研几个方案。说实话，市面上的知识库产品真的是五花八门，什么Confluence、Notion、语雀啥的，但要么收费贵得离谱，要么功能不够用。偶然间发现了PandaWiki这个开源项目，试用了一下发现还真不错。界面简洁，功能够用，关键是免费！今天就把我搭建的整个过程分享给大家，希望能帮到有需要的朋友。什么是PandaWiki项目地址：https://github.com/chaitin/PandaWiki演示体验demo：https://192.168.198.133:2443/doc/editor/019a131f-12df-759c-a1a9-194d3c5ae47cPandaWiki是一个基于Go语言（好多项目都是go开发的，看来确实得学go了！！！）开发的轻量级知识库系统，支持Markdown编辑，有着不错的用户体验。相比其他重量级的知识库系统，它的部署和维护都相对简单。我之前用过MediaWiki，那个配置起来真的是要命，光是数据库配置就能折腾半天。PandaWiki就不一样了，基本上几个命令就能跑起来。环境准备在开始之前，我们需要准备一台Linux服务器。我这里用的是Debian 13（老演员了！），配置是2核4G，对于小团队使用完全够了。首先更新一下系统：apt update && apt upgrade -y然后安装一些必要的工具：apt install -y wget curl git vim开始部署PandaWiki一条命令搞定安装！！舒服！bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)"选择安装还是升级！会让你确认安装目录，无脑回车就行，也是通过docker部署(最喜欢看这种安装界面了哈哈哈哈)还有交流群二维码！！哈哈哈初始化配置打开浏览器访问 http://你的服务器IP:8080，应该能看到PandaWiki的初始化页面。第一次访问会要求你创建管理员账户。我建议用户名不要用admin这种太常见的，密码也要设置复杂一点。初始化完成后，你就能看到一个干净的知识库界面了。界面还是挺清爽的，左侧是目录树，右侧是内容区域。让你配置大模型很丰富注册靠谱白嫖一个（不是广告！）基本使用新手文档：https://192.168.198.133:2443/doc/editor/019a131f-12da-76b3-bafe-3cfbe1069e69创建文档点击"新建文档"按钮，可以选择创建普通文档或者文件夹。PandaWiki支持Markdown语法，写起来还是很顺手的。我试着创建了几个测试文档，发现它的Markdown渲染效果还不错，代码高亮、表格、图片都支持得挺好。我这里直接通过rss来导入自己博客的文档！通过rss订阅可以直接拉取很多地方的操作文档！这是拉取到的博客文章：去发布导入本地文本这就是财富！！！发布！！！使用统计！常用配置使用体验用了一段时间下来，感觉PandaWiki还是挺不错的。界面简洁，功能够用，性能也还可以。我们团队大概20多个人在用，响应速度还是很快的。当然也有一些不足的地方，比如权限管理相对简单，插件生态也不够丰富。但对于大多数中小团队来说，这些功能已经够用了。最重要的是它是开源免费的，不用担心突然收费或者服务停止。而且代码托管在GitHub上，如果有需要还可以自己修改。我感觉很nice！！会给出具体的引用，我准备用这个来替代我的博客搜索了哈哈哈写在最后PandaWiki作为一个轻量级的知识库解决方案，确实有它的优势。部署简单，维护方便，功能够用，关键是免费开源。虽然在一些高级功能上可能不如商业产品，但对于大多数团队来说已经足够了。特别是对于预算有限的小团队，这绝对是个不错的选择。如果你也在寻找知识库解决方案，不妨试试PandaWiki。反正是免费的，试试又不会怀孕。部署过程中如果遇到问题，可以查看官方文档或者GitHub上的issue。社区虽然不大，但还是比较活跃的。好了，今天的分享就到这里。如果这篇文章对你有帮助，记得点个赞转发一下。有问题的话也可以在评论区留言，我看到会回复的。如果这篇文章对你有帮助，别忘了点赞转发支持一下！想了解更多运维实战经验和技术干货，记得关注微信公众号@运维躬行录，领取学习大礼包！！！我会持续分享更多接地气的运维知识和踩坑经验。让我们一起在运维这条路上互相学习，共同进步！公众号：运维躬行录个人博客：躬行笔记

Python sh库：让运维脚本告别subprocess的痛苦，一行代码搞定系统命令
type: item
date: 2025-10-21T14:27:45+00:00
description: 最近在整理服务器监控脚本的时候，发现自己写的代码里到处都是subprocess.Popen()，看着就头疼。想起刚入行那会儿，为了执行个简单的ls命令，愣是写了十几行代码处理各种异常和输出，现在想想真是太蠢了。直到遇到了Python的sh库，我才发现原来执行系统命令可以这么优雅。今天就来聊聊这个让我爱不释手的库，相信看完之后你也会和我一样，再也不想碰subprocess了。为什么我会选择sh库说实话，Python标准库里的subprocess功能很强大，但用起来真的很繁琐。每次想执行个简单命令都要考虑一堆问题：怎么获取输出？怎么处理错误？怎么传参数？import subprocess # 传统的subprocess写法，光看着就累 result = subprocess.run(['ls', '-la'], capture_output=True, text=True, check=True) print(result.stdout)而用sh库呢？import sh print(sh.ls('-la'))就这么简单！一行代码搞定，看着就舒服多了。sh库的安装和基本使用安装很简单，pip一下就行：pip install sh基本使用更简单，直接把系统命令当成Python函数调用就可以了：import sh # 执行ls命令 print(sh.ls()) # 带参数的命令 print(sh.ls('-la', '/home')) # 管道操作也很简单 print(sh.grep(sh.ps('aux'), 'python'))我第一次看到这种写法的时候，真的被震撼到了。这不就是我一直想要的那种简洁的方式吗？实际项目中的应用场景在我日常运维中，sh库真的帮了大忙。比如说服务器健康检查脚本：import sh from datetime import datetime def check_server_status(): # 检查磁盘使用情况 disk_usage = sh.df('-h') print(f"磁盘使用情况：\n{disk_usage}") # 检查内存使用 memory_info = sh.free('-h') print(f"内存使用情况：\n{memory_info}") # 检查CPU负载 load_avg = sh.uptime() print(f"系统负载：{load_avg}") # 检查特定进程 try: nginx_processes = sh.pgrep('nginx') print(f"Nginx进程数：{len(nginx_processes.strip().split())}") except sh.ErrorReturnCode_1: print("警告：Nginx进程未运行！")这种写法比subprocess清爽太多了，而且代码可读性特别好。处理命令输出和错误sh库在处理命令输出方面也很贴心：import sh # 获取命令输出 output = sh.ls('/home') print(type(output)) # <class 'sh.RunningCommand'> print(str(output)) # 转换为字符串 # 实时处理输出 def process_line(line): print(f"处理行: {line.strip()}") sh.tail('-f', '/var/log/syslog', _out=process_line)错误处理也很直观：import sh try: # 执行可能失败的命令 result = sh.ls('/nonexistent') except sh.ErrorReturnCode_2 as e: print(f"命令执行失败: {e}") print(f"错误输出: {e.stderr}") print(f"标准输出: {e.stdout}") print(f"退出码: {e.exit_code}")高级功能：管道和重定向sh库对管道的支持让我印象深刻，写起来就像在shell里一样自然：import sh # 管道操作 result = sh.ps('aux') | sh.grep('python') | sh.wc('-l') print(f"Python进程数量: {result}") # 更复杂的管道 log_errors = sh.tail('-n', '1000', '/var/log/app.log') | sh.grep('ERROR') print(log_errors) # 重定向到文件 sh.dmesg(_out='/tmp/dmesg.log') # 从文件读取输入 sh.sort(_in='/tmp/unsort…

CDN优化实战：从命中率30%到95%的血泪史，AWS CloudFront踩坑全记录
type: item
date: 2025-10-16T14:14:55+00:00
description: 最近客户cdn命中率异常，让我优化下缓存策略。经过一番折腾，总算把命中率提上来了！！！今天就把这些年踩过的坑和一些实用的经验分享给大家。其实CDN优化这事儿，说简单也简单，说复杂也复杂。很多人以为接入个CDN就万事大吉了，结果发现命中率低得可怜，钱花了不少效果却不明显。我之前就遇到过这种情况，CDN命中率只有30%多，简直是在烧钱。先说说CDN的那些关键指标做CDN优化，你得先知道怎么看数据。就像开车要看仪表盘一样，不然怎么知道车子跑得怎么样？命中率（Hit Ratio）这个是最重要的指标，没有之一。命中率就是CDN直接返回缓存内容的请求占总请求的比例。一般来说，静态资源的命中率应该在90%以上，如果你的命中率只有50-60%，那肯定有问题。在AWS CloudFront里查看命中率很简单，进入CloudFront控制台，选择你的分发，然后点击"Monitoring"标签页。这里会显示Cache hit rate的图表，可以看到不同时间段的命中率变化。回源率（Origin Request Rate）这个和命中率是相对的，回源率高说明CDN经常要去源站拿数据，这样就失去了CDN的意义。正常情况下回源率应该控制在10%以下。响应时间包括CDN响应时间和回源响应时间。CDN响应时间一般应该在100ms以内，如果超过这个数值就要检查是不是节点选择有问题。我记得有次优化一个电商网站，发现图片加载特别慢。一查监控发现CDN响应时间居然有2秒多，后来才发现是缓存策略配置错误，每次都要回源验证。带宽使用情况这个主要是看成本，CDN的费用很大一部分就是带宽费用。通过监控带宽使用情况，可以了解流量分布，优化成本。在AWS CloudFront的监控面板里，你还能看到：Origin latency（回源延迟）Error rate（错误率）Requests（请求数）Bytes downloaded（下载字节数）这些数据都很有用，特别是错误率，如果突然飙升可能是源站出问题了。命中率低的常见原因和解决方案说到命中率低，我遇到过各种奇葩的情况。缓存策略配置不当这是最常见的问题。很多人图省事，直接用默认配置，结果发现很多本该缓存的内容都没有缓存。比如说，有些动态参数会导致URL不同，CDN就认为是不同的资源。像这种情况：https://example.com/image.jpg?timestamp=1234567890 https://example.com/image.jpg?timestamp=1234567891CDN会认为这是两个不同的文件，实际上内容是一样的。解决办法是在CloudFront的Behavior设置里配置Query String参数处理，可以选择忽略某些参数或者只转发特定参数。TTL设置太短Time To Live设置太短会导致缓存频繁过期。我见过有人把图片的TTL设置成5分钟，这不是瞎搞吗？静态资源的TTL至少要设置几个小时，甚至几天。在CloudFront里可以设置三种TTL：Minimum TTL：最小缓存时间Maximum TTL：最大缓存时间Default TTL：默认缓存时间一般我会这样设置：图片、CSS、JS等静态资源：24小时到7天HTML页面：1-6小时API接口：根据业务需求，可能几分钟到几小时源站响应头配置问题有时候源站返回了不合适的Cache-Control头，比如no-cache或者max-age=0，这会导致CDN不缓存内容。我之前遇到过一个案例，开发在Nginx配置里给所有静态资源都加了no-cache，结果CDN命中率惨不忍睹。后来改成这样：location ~* \.(jpg|jpeg|png|gif|css|js)$ { expires 7d; add_header Cache-Control "public, immutable"; }预热不充分新上线的CDN或者清除缓存后，需要一段时间来"预热"。这期间命中率会比较低，这是正常现象。但如果长时间命中率都上不去，就要检查其他配置了。CloudFront支持手动预热，可以通过Invalidation功能清除缓存，然后用脚本批量访问重要资源来预热缓存。CDN优化策略详解现在说说aws托管的缓存策略AWS CDN托管的缓存策略详细说明策略名称缓存内容不缓存内容使用场景Amplify缓存大多数静态资源和部分动态内容不缓存包含特定身份验证头的请求Amplify应用程序的通用缓存策略Amplify-Default缓存静态资源和基于常用头部的内容，保留某些Cookie不缓存带有特定认证头的请求，某些动态API响应Amplify应用的标准配置，平衡缓存与个性化Amplify-Default-V2与Amplify-Default类似，但有优化的TTL设置与Ampli…

博客更新！！！
type: item
date: 2025-09-21T14:15:20+00:00
description: 博客终于大更新啦！之前那个默认主题比较简单！除了博客文章不能给粉丝盆友带来什么价值。所以我在修改后的页面上加了一个导航页。希望能够激你大家收藏的欲望（大家有什么更好的建议也欢迎在评论区提哈，感谢支持！！！）主要变动：1、添加白天黑夜主题切换2、修改logo3、添加导航页，这个我会持续更新，欢迎大家收藏，有事没事来逛逛4、添加个人介绍页面5、优化页面样式，响应式布局采用DaisyUI + Tailwind CSS构建，提供简洁优雅的设计风格和丰富的功能特性。主题注重用户体验和响应式设计。DaisyUI官网地址：https://daisyui.com/Tailwind CSS官网地址：https://tailwindcss.com/

云计算专业术语大揭秘！这些"黑话"你都懂吗？
type: item
date: 2025-07-02T14:44:27+00:00
description: 最近在公司开会，听到同事们各种云计算术语满天飞，什么"弹性伸缩"、"容器编排"、"微服务架构"...说实话，刚入行那会儿我也是一脸懵，感觉大家说的都是外星语。做了这么多年运维，我发现很多朋友都有这样的困扰：技术文档看不懂，会议听不明白，跟开发沟通像是在打哑谜。其实云计算的这些专业术语并没有想象中那么高深，今天我就来给大家捋一捋，用最接地气的方式解释这些"黑话"。基础设施即服务，听起来很高大上IaaS（Infrastructure as a Service），翻译过来就是基础设施即服务。简单说就是云服务商把服务器、存储、网络这些硬件资源虚拟化之后租给你用。我记得以前公司要上个新项目，得先采购服务器，等设备到货，然后机房上架，网络配置...整个流程下来至少要一个月。现在用云服务，几分钟就能开出一台虚拟机，这就是IaaS的魅力。PaaS（Platform as a Service）更进一步，不仅提供基础设施，还提供了开发和运行环境。比如你要部署一个Java应用，传统方式需要自己安装JDK、配置Tomcat、设置数据库连接等等。用PaaS的话，这些环境都给你准备好了，你只需要把代码扔上去就行。SaaS（Software as a Service）就更直接了，软件即服务。像我们平时用的钉钉、腾讯会议、Office 365都属于SaaS。用户不需要安装任何软件，打开浏览器就能使用。说到这里想起个笑话，有次我跟一个做传统IT的朋友聊天，他问我："你们云计算到底是干什么的？"我说："就是把别人的电脑当自己的电脑用。"他恍然大悟："那不就是网吧模式吗？"...虽然这个比喻不太准确，但某种程度上还真有点像。虚拟化技术，一台机器变多台虚拟化（Virtualization）是云计算的基石。通过虚拟化技术，一台物理服务器可以运行多个虚拟机，每个虚拟机都像是一台独立的计算机。Hypervisor是虚拟化的核心组件，负责管理和分配物理资源给各个虚拟机。常见的有VMware vSphere、Microsoft Hyper-V、开源的KVM等。容器（Container）是另一种虚拟化技术，比传统虚拟机更轻量级。如果说虚拟机是把一栋楼分成若干套房子，那容器就是把一套房子分成若干个房间。Docker是目前最流行的容器技术。我刚接触Docker的时候觉得特别神奇，一个应用连同它的运行环境可以打包成一个镜像，在任何支持Docker的机器上都能运行。这解决的是运行环境标准化的问题，避免了“一杯茶一包烟，一个环境配一天”的悲剧发生。容器编排（Container Orchestration）就是管理大量容器的技术。想象一下，如果你有成百上千个容器需要管理，手工操作肯定要疯掉。Kubernetes（简称K8s）是目前最主流的容器编排平台，虽然学习曲线比较陡峭，但掌握之后确实很强大。弹性和可扩展性，云计算的杀手锏弹性伸缩（Auto Scaling）是云计算的一大优势。系统可以根据负载情况自动增加或减少资源。比如电商网站在促销期间访问量暴增，系统会自动启动更多服务器来应对；活动结束后又会自动释放多余的资源。传统电商公司活动页面，平时访问量很少，但每次做活动就会有大量用户涌入。以前总是要提前评估流量，手动扩容，经常出现要么资源不够导致页面卡顿，要么准备过多造成浪费。现在配置了弹性伸缩，系统会根据CPU使用率和响应时间自动调整，省心多了。负载均衡（Load Balancing）是把请求分发到多个服务器上，避免某台服务器过载。就像银行有多个窗口，客户排队时会被引导到空闲的窗口一样。CDN（Content Delivery Network）内容分发网络，把静态资源缓存到离用户最近的节点上，加快访问速度。比如你在北京访问一个网站，如果服务器在深圳，数据要跑很远；但如果在北京有CDN节点，就能就近获取内容。按量计费，云计算的经济学革命说到云计算，不得不提它最吸引人的特点之一——按量计费。这个模式彻底改变了企业的IT成本结构。传统IT模式下，你要上个项目，先得买服务器、买软件许可证、租机房位置...这些都是一次性的大笔投入。以前公司要上个ERP系统，光硬件采购就花了几十万，结果项目上线后发现性能过剩，大部分资源都闲置着。更要命的是，三年后硬件过保了，又得花钱升级。云计算的按量计费就像用水用电一样，用多少付多少。你的应用今天访问量大，系统自动扩容，多用了资源就多付费；明天访问量小，资源自动释放，费用也跟着降下来。比如某电商公司，平时一天可能就几百个访问，但做促销活动的时候一小时就有几万个访问。以前为了应对峰值流量，得准备足够的服务器，但99%的时间这些服务器都在"睡觉"。现在用云服务，平时只需要一台小配置的虚拟机，活动期间自动扩展到十几台，活动结束又缩回去。算下来一年能省好几万块。按需付费（Pa…

python实现币安监控
type: item
date: 2025-04-28T02:48:00+00:00
description: 前言最近一个盆友提了一个需求，想要通过币安公开接口实时关注指定币种类价格，然后达到指定阈值后通过飞书发送消息。既然是盆友那忙肯定得帮。具体步骤币安接口分析https://developers.binance.com/docs/zh-CN/binance-spot-api-docs/web-socket-streams，这是api文档。有其他需求的朋友可以根据文档来对接指定api。因为高频要求，本次直接使用WebSocket调用，不使用rest api。关于python WebSocket库的使用可以参考这篇文章，https://blog.csdn.net/liaoqingjian/article/details/146908212核心功能分析高频数据采集：通过币安REST API获取所有现货交易对信息，这样避免手动更新币种通过WebSocket实时订阅交易对的ticker数据按批次订阅，每批100个交易对，避免单个连接订阅过多价格监控：记录每个交易对最近1分钟的价格历史计算1分钟内的价格涨跌幅当涨跌幅超过设定阈值(3%)时触发警报警报机制：通过飞书Webhook发送警报消息实现冷却期机制，避免同一交易对短时间内重复发送警报警报包含交易对、涨跌幅、价格变化、成交量等信息程序源码import json import asyncio import websockets import requests from datetime import datetime import time class BinanceSpotMonitor: def __init__(self, feishu_webhook_url): self.ws_url = "wss://stream.binance.com:9443/ws" self.rest_api_url = "https://api.binance.com/api" self.feishu_webhook_url = feishu_webhook_url self.market_data = {} self.batch_size = 100 # 每批订阅的交易对数量 self.price_history = {} # 存储价格历史 self.alert_threshold = 3.0 # 涨跌幅阈值，超过此值将触发推送 self.alert_cooldown = {} # 用于控制推送频率，避免同一币种短时间内多次推送 self.cooldown_period = 60 # 冷却时间(秒)，同一币种在此时间内只推送一次 async def get_spot_symbols(self): """获取所有现货交易对，仅保留USDT交易对""" try: response = requests.get(f"{self.rest_api_url}/v3/exchangeInfo") response.raise_for_status() symbols = [] for symbol in response.json()["symbols"]: # 只保留以USDT结尾的交易对 if (symbol["status"] == "TRADING" and symbol["isSpotTradingAllowed"] and symbol["quoteAsset"] == "USDT"): symbols.append({ "symbol": symbol["symbol"], "baseAsset": symbol["baseAsset"], "quoteAsset": symbol["quoteAsset"] }) return symbols except Exception as e: print(f"获取交易对列表失败: {e}") return [] async def connect_and_subscribe_batch(self, symbols_batch): """连接到币安WebSocket并订阅一批市场的ticker数据""" try: async with websockets.connect(self.ws_url) as websocket: # 创建订阅请求 subscribe_request = { "method": "SUBSCRIBE", "params": [f"{symbol['symbol'].lower()}@ticker" for symbol in symbols_batch], "id": 1 } # 发送订阅请求 await websocket.send(json.dumps(subscribe_request)) # 接收订阅确认 respons…

微信多开脚本
type: item
date: 2025-04-21T14:07:00+00:00
description: 前言有几个微信需要多开登录，每次都要按回车点击微信多开。把握不住，老是会开很多个。用python实现多开，精准控制需要打开的数量，但是打开前先要关闭所有微信。运行图片：源码import tkinter as tk import subprocess import os import time from tkinter import messagebox, ttk class WeChatMultiOpener: def __init__(self, root): self.root = root self.root.title("微信多开器") self.root.geometry("300x200") self.root.resizable(False, False) # 设置界面 self.setup_ui() def setup_ui(self): # 主框架 main_frame = tk.Frame(self.root, padx=20, pady=20) main_frame.pack(fill=tk.BOTH, expand=True) # 标题标签 title_label = tk.Label(main_frame, text="微信多开工具", font=("Arial", 14, "bold")) title_label.pack(pady=10) # 数量选择框架 count_frame = tk.Frame(main_frame) count_frame.pack(pady=10, fill=tk.X) # 数量标签 count_label = tk.Label(count_frame, text="打开数量:") count_label.pack(side=tk.LEFT, padx=(0, 5)) # 数量输入框 self.count_var = tk.StringVar(value="2") count_spinbox = ttk.Spinbox( count_frame, from_=1, to=10, width=5, textvariable=self.count_var ) count_spinbox.pack(side=tk.LEFT) # 按钮框架 button_frame = tk.Frame(main_frame) button_frame.pack(pady=10) # 打开微信按钮 open_button = tk.Button(button_frame, text="打开微信", width=12, command=self.open_multiple_wechat, bg="#1aad19", fg="white") open_button.pack(side=tk.LEFT, padx=5) # 关闭所有微信按钮 close_button = tk.Button(button_frame, text="关闭所有微信", width=12, command=self.close_all_wechat) close_button.pack(side=tk.LEFT, padx=5) # 状态标签 self.status_var = tk.StringVar(value="就绪") status_label = tk.Label(main_frame, textvariable=self.status_var, fg="gray") status_label.pack(pady=(10, 0)) def open_multiple_wechat(self): try: # 获取用户输入的数量 count_text = self.count_var.get().strip() try: count = int(count_text) if count < 1 or count > 10: messagebox.showwarning("警告", "请输入1-10之间的数字") return except ValueError: messagebox.showwarning("警告", "请输入有效的数字") return wechat_path = r"C:\Program Files\Tencent\WeChat\WeChat.exe" # 检查路径是否存在 if not os.path.exists(wechat_path): print("未找到微信程序，请检查安装路径") return # 更新状态 self.status_var.set(f"正在打开 {count} 个微信实例...") self.root.update() # 打开指定数量的微信 for i in r…

Python还能这么用？U盘加密工具保护你的秘密
type: item
date: 2025-04-18T14:35:00+00:00
description: 前言存u盘里内容（老师）不想让别人知道，那就写个u盘加密工具来守护它把！何为u盘加密？加密U盘是指对U盘内容有加解密保护功能的U盘。市面上的加密U盘主要有三类：A．假加密，仅仅是隐藏文件，设个密码，仅仅验证身份，实际存储内容没有任何变化。B．软加密，内置或附带软件，对数据进行加密，一般用AES，也可分加密区及非加密区。C．硬件加密，内置硬件加密，透明加密，无形之中，完成加密，读取时验证，有的具有一些特殊功能，例如将加密应用于硬盘，插上U盘显示明码，拔下显示就是加密信息。柿子要挑软的捏，那我们就从软加密入手吧。核心功能概述1、使用Fernet对称加密（基于AES-128-CBC），常用的对称加密方式。2、使用SHA-256哈希存储密码，PBKDF2派生加密密钥3、加密后将原文件删除，解密后恢复原始文件结构，这样可以隐藏源文件。4、基于Tkinter的简单GUI界面，简单，但是界面不是很美观，后期可以用ttkbootstrap美化下界面。运行截图加密前：加密后：解密：关键组件分析1. 密钥管理机制def hash_password(self, password): """对密码进行哈希""" return hashlib.sha256(password.encode()).hexdigest() def derive_key(self, password): """从密码派生加密密钥""" kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=self.salt, iterations=self.config["encryption_settings"]["key_iterations"], ) key = base64.urlsafe_b64encode(kdf.derive(password.encode())) return key使用PBKDF2密钥派生函数，通过多次迭代（默认100,000次）增强安全性使用固定盐值（self.salt = b'USBEncryptionSalt123'），简化密钥管理但降低了安全性密码验证使用SHA-256哈希，存储在配置文件中2. 文件加密流程def encrypt_usb(self, password): # ... # 创建Fernet加密器 key = self.derive_key(password) fernet = Fernet(key) # 打开加密数据文件 with open(self.data_file, 'wb') as data_file: # 写入文件数量 data_file.write(struct.pack("<I", total_files)) # 加密并写入每个文件 for i, file_path in enumerate(files_to_encrypt): # 读取文件内容 with open(file_path, 'rb') as f: file_data = f.read() # 获取相对路径 rel_path = os.path.relpath(file_path, self.usb_root) rel_path_bytes = rel_path.encode('utf-8') # 加密文件内容 encrypted_data = fernet.encrypt(file_data) # 写入路径长度、路径和加密数据 data_file.write(struct.pack("<I", len(rel_path_bytes))) data_file.write(rel_path_bytes) data_file.write(struct.pack("<Q", len(encrypted_data))) data_file.write(encrypted_data) # 删除原文件 os.remove(file_path) # ...所有文件内容被加密并集中存储在一个单一的加密数据文件（.usbenc_data.bin）中文件结构信息（相对路径）也被保存，以便解密时恢复原始目录结构使用二进制格式存储，包含文件数量、路径长度、路径、加密数据长度和加密数据3. 文件解密流程def decrypt_usb(self, password): # ... # 创建Fernet解密器 key = self.derive_key(password) fernet = Fernet(key) # 打开加密数据文件 with open(self.data_file, 'rb') as data_file: # 读取文件数量 total_files = struct.unpack("<I", data_…