微信图片批量保存的办法

news/2025/10/3 22:17:24/文章来源:https://www.cnblogs.com/swtjavaspace/p/19125090

已经给官方提建议了,目前还没在最新版看到相关功能。

解决办法:python 脚本(通过pywinauto 控制点击下一张和下载按钮,然后通过判断文件夹里的文件md5值重复阈值来间接达到判断没有下一张的目的)

操作步骤,登录电脑版微信,打开相关聊天记录,打开图片查看功能,界面是这个样子的才能用这个脚本(忽略第二个按钮置灰,刚跑完一次)。

a

 

 

 

 

 

此时是可以点击左上角向右箭头(从左数第二个按钮:鼠标放上去提示文字为下一张)和另存为按钮(顶部最右侧的按钮)的,先点即下载按钮,选择保存路径

比如我选择的是 C:\Users\e3724\Desktop\a 
那么将这个路径在下面python脚本中有用到

from pywinauto import Application
import time
import os
import hashlib
import threading
from pywinauto.keyboard import send_keys
from collections import defaultdict# 配置参数
SAVE_FOLDER = r"C:\Users\e3724\Desktop\a"  # 目标保存路径
MAX_REPEAT = 2  # MD5重复阈值(达到此次数则停止)
WAIT_DELAY = 0.01  # 操作延迟(秒),如果在电脑上图片没被看过,则此数字要调大至1.0~3.0左右,因为第一次用网络加载需要时间
MONITOR_INTERVAL = 1  # 监控线程扫描间隔(秒)# 全局变量:文件名→MD5映射(线程安全)
file_md5_map = {}
# 全局变量:MD5出现次数统计
md5_count = defaultdict(int)
# 线程锁
map_lock = threading.Lock()def calculate_md5(file_path):"""计算文件MD5值"""if not os.path.exists(file_path):return Nonetry:hash_md5 = hashlib.md5()with open(file_path, "rb") as f:for chunk in iter(lambda: f.read(4096), b""):hash_md5.update(chunk)return hash_md5.hexdigest()except Exception as e:print(f"计算MD5失败:{str(e)}")return Nonedef folder_monitor():"""后台线程:监控文件夹并更新MD5映射"""global file_md5_map, md5_countwhile True:if os.path.exists(SAVE_FOLDER):for filename in os.listdir(SAVE_FOLDER):if filename.endswith(".jpg") and filename.split(".")[0].isdigit():file_path = os.path.join(SAVE_FOLDER, filename)with map_lock:current_md5 = calculate_md5(file_path)if current_md5:# 处理文件更新(如覆盖保存)if filename in file_md5_map:old_md5 = file_md5_map[filename]md5_count[old_md5] -= 1if md5_count[old_md5] <= 0:del md5_count[old_md5]# 更新映射和计数file_md5_map[filename] = current_md5md5_count[current_md5] += 1time.sleep(MONITOR_INTERVAL)def wait_for_file(filename, timeout=10):"""等待文件被监控线程捕获"""start_time = time.time()while time.time() - start_time < timeout:with map_lock:if filename in file_md5_map:return Truetime.sleep(0.5)return Falsedef final_dedup():"""流程结束后统一删除重复文件(只保留第一个出现的)"""with map_lock:# 按文件名排序(确保按顺序保留第一个)sorted_files = sorted(file_md5_map.keys(), key=lambda x: int(x.split(".")[0]))md5_first_occurrence = {}  # 记录MD5首次出现的文件名duplicate_files = []       # 记录重复文件for filename in sorted_files:md5 = file_md5_map[filename]if md5 not in md5_first_occurrence:md5_first_occurrence[md5] = filenameelse:duplicate_files.append(filename)# 删除重复文件for filename in duplicate_files:file_path = os.path.join(SAVE_FOLDER, filename)if os.path.exists(file_path):try:os.remove(file_path)print(f"最终去重:删除重复文件 {filename}")except Exception as e:print(f"删除重复文件失败 {filename}:{str(e)}")return len(sorted_files) - len(duplicate_files), len(duplicate_files)def auto_download_wechat_images(window_title, next_btn_text="下一张", save_btn_text="另存为"):# 记录开始时间start_time = time.time()try:# 启动监控线程monitor_thread = threading.Thread(target=folder_monitor, daemon=True)monitor_thread.start()print("已启动文件夹监控线程...")time.sleep(2)# 连接窗口app = Application(backend="uia").connect(title_re=f".*{window_title}.*", timeout=10)main_window = app.window(title_re=f".*{window_title}.*")main_window.set_focus()print(f"已连接到窗口:{main_window.window_text()}")click_count = 1stop_flag = Falsewhile not stop_flag:# 查找下一张按钮next_btn = Nonefor btn in main_window.descendants(control_type="Button"):btn_text = btn.window_text().strip()if next_btn_text in btn_text or "→" in btn_text:next_btn = btnbreakif not next_btn or not next_btn.is_enabled():print("未找到可用的下一张按钮,停止流程")break# 查找另存为按钮save_btn = Nonefor btn in main_window.descendants(control_type="Button"):btn_text = btn.window_text().strip()if save_btn_text in btn_text or "保存" in btn_text:save_btn = btnbreakif not save_btn or not save_btn.is_enabled():print("未找到可用的另存为按钮,跳过")next_btn.click_input()click_count += 1time.sleep(WAIT_DELAY)continue# 保存当前图片current_filename = f"{click_count}.jpg"print(f"\n===== 处理第{click_count}张图片({current_filename})=====")save_btn.click_input()time.sleep(WAIT_DELAY )  # 等待对话框# 输入文件名(重试机制)save_success = Falsefor _ in range(3):try:send_keys(current_filename.split(".")[0])  # 输入数字time.sleep(0.5)send_keys("{ENTER}")save_success = Truebreakexcept:time.sleep(1)if not save_success:print("保存失败,跳过")next_btn.click_input()click_count += 1continue# 等待文件被监控线程捕获if not wait_for_file(current_filename):print(f"警告:{current_filename} 未被监控到,可能保存路径错误")next_btn.click_input()click_count += 1continue# 检查MD5重复情况with map_lock:current_md5 = file_md5_map[current_filename]current_md5_count = md5_count[current_md5]print(f"当前MD5:{current_md5},累计出现次数:{current_md5_count}")# 首次重复时输出日志if current_md5_count == 2:print(f"⚠️ MD5首次重复(当前文件:{current_filename})")# 达到重复阈值时停止流程elif current_md5_count >= MAX_REPEAT:print(f"⚠️ MD5重复达到阈值({MAX_REPEAT}次),停止流程")stop_flag = Truebreak# 点击下一张next_btn.click_input()click_count += 1time.sleep(WAIT_DELAY * 2)# 流程结束后统一去重print("\n开始最终去重...")total_valid, total_duplicate = final_dedup()# 计算总耗时end_time = time.time()total_time = end_time - start_timeminutes = int(total_time // 60)seconds = total_time % 60print(f"\n===== 结果统计 =====")print(f"总下载文件数:{len(file_md5_map)}")print(f"去重后保留:{total_valid} 张")print(f"删除重复文件:{total_duplicate} 张")print(f"总耗时:{minutes}分{seconds:.2f}秒")except Exception as e:# 异常时也统计耗时end_time = time.time()total_time = end_time - start_timeprint(f"流程出错:{str(e)},已运行{total_time:.2f}秒")if __name__ == "__main__":input("请确认路径正确且手动测试过保存功能,按回车开始...")auto_download_wechat_images(window_title="图片查看",next_btn_text="下一张",save_btn_text="另存为")

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/926382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站运营专员具体每天怎么做网站建设收费标准报价

ps&#xff1a; 为啥不用蒲公英了&#xff0c;就是因为有广告了&#xff0c;获取个UDID还安装游戏&#xff0c;真恶心?&#xff0c;所以找了新的获取UDID都方法&#xff0c;网页直接获取就可以&#xff0c;不会安装软件。 UDID 是一种 iOS 设备的特殊识别码。除序号之外&…

详细介绍:使用 C# 设置 Excel 单元格数据验证

详细介绍:使用 C# 设置 Excel 单元格数据验证pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

乐清人才网官方网站深圳建网站公司哪家好

原理图&#xff1a; 矩阵按键原理图&#xff1a; 实验板接口原理图&#xff1a; 得到对应图&#xff1a; 扫描按键原理&#xff1a; 按键的COLUMN1、2、3分别制0&#xff0c;每次只允许其中一个为0其他都是1&#xff08;POW1和POW2正常状况为上拉&#xff09;&#xff0c;当有…

博客园实验1

1 // 打印一个字符小人 2 #include <stdio.h> 3 int main() 4 { 5 printf(" O \n"); 6 printf("<H>\n"); 7 printf("I I\n"); 8 return 0; 9 }View Code1 …

做盗版系统网站会不会php app网站建设

本书目录&#xff1a;点击进入 一、总结内容 二、习题 2.1 【选择题】以下Vue指令中&#xff0c;哪些指令具备简写方式&#xff1f; 2.2 【编程题】以下Vue指令中&#xff0c;哪些指令具备简写方式&#xff1f; &#xff1e; 效果 &#xff1e; 代码 一、总结内容 了解核…

arm汇编

寄存器 R0–R3 传参/返回值 R4–R11 局部变量(callee 保存) R12 临时 R13 SP 栈指针 R14 LR 返回地址 R15 PC 程序计数器 CPSR 标志位:N Z C V 常用指令 MOV Rd, #imm 立即数传送 ADD/ADC…

腾度网站建设品牌营销模式

前段时间&#xff0c;家里的iPad被家人误操作&#xff0c;导致iPad变成不可使用状态。自己折腾了半天&#xff0c;没有找到解决办法。没有办法&#xff0c;只好拿到手机维修店去修理,很快就修理好了.其实也很简单--就是对iPad进行了刷机操作。当然我也看到了刷机的方法。今天&a…

模型与分词器

当我们说“让AI理解人类语言”时,第一步是什么? 计算机是无法直接处理文本的,它需要数字。而模型与分词器就是完成“文本 → 数字 → 理解”这个神奇转换的关键二人组。本文将带你彻底理解这两者是什么、如何工作以…

云锵投资 2025 年 9 月简报

季报摘要本季度,量化基金策略业绩:15.48%,中,全国排名:8672/13200;平均 Beta:1.00; 本季度,量化股票策略业绩:25.05%,良,全国排名:4926/13200;平均 Beta:1.61; 本季度,量化期权策略业绩:21.71%(中性…

subclipse最新版本更新地址

subclipse最新版本更新地址 https://gitcode.com/gh_mirrors/upda/updates/tree/main/subclipse

详细介绍:C++与Open CASCADE中的STEP格式处理:从基础到高级实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

板子2

最近经常跑到以前代码里复制的东西,其实简单。 其中逆序对甚至vp的时候开始写了个挂的,和将军手搓了半天。 干脆放这里备用。 【模版】逆序对 【模版】笛卡尔树

简单网站开发项目实例企业网址是怎么写的

提起SimpleDateFormat类&#xff0c;想必做过Java开发的童鞋都不会感到陌生。没错&#xff0c;它就是Java中提供的日期时间的转化类。这里&#xff0c; 为什么说SimpleDateFormat类有线程安全问题呢&#xff1f;有些小伙伴可能会提出疑问&#xff1a;我们生产环境上一直在使用S…

网站搭建多少钱徐州百都网络非常好网站建设代码怎么导入图片

我一直不知道我在大家心目中的定位是什么&#xff0c;但我内心其实是把自己定义为一个『工具人』的。可能是因为我自己本身就是程序员&#xff0c;所以更能理解程序员的不易吧。所以&#xff0c;我尽量不写水文&#xff0c;只分享干货。就是希望大家看了能够有所收获&#xff0…

从DQN到Double DQN:分离动作选择与价值评估,解决强化学习中的Q值过估计问题

2015年DQN在Atari游戏上取得突破性进展,从此以后强化学习终于能处理复杂环境了,但没多久研究者就注意到一些奇怪的现象: Q值会莫名其妙地增长到很大,智能体变得异常自信,坚信某些动作价值极高。实际跑起来却发现这…

P9877/QOJ5069 Vacation

题意 给定长度为 \(n\) 的序列 \(a\) 和定值 \(c\),\(q\) 次操作,每次操作可以是单点修改,也可以是查询 \([l,r]\) 的所有区间长度 \(\le c\) 的子区间中区间和最大是多少。 \(c\le n\le 2\times10^5,q\le 5\times1…

CF1916G Optimizations From Chelsu

神仙题,神仙做法。点分治,假设路径的端点是 \(s\) 和 \(t\),那么 \(len\times g\) 就是 \((d_s+d_t)\times \gcd(v_s,v_t)\),其中 \(d\) 是到根链长度,\(v\) 是到根的 \(\gcd\)。 不妨设 \(d_s\ge d_t\),那么 \(…

详细介绍:微服务架构:基于Spring Cloud ,构建同城生活服务平台

详细介绍:微服务架构:基于Spring Cloud ,构建同城生活服务平台pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "…

【游记】北京师范大学讲课

【游记】北京师范大学讲课好久没有写长文了,今天很有兴致,写一篇罢! ccpc 网络赛前一天 去北京参加 tower research 举办的宣讲会。结束后和 yzf 找芈重山吃,海淀桥店人满为患,于是跑到了五道口,发现也是人满为患…

做网站 带宽 多少钱厦门国外网站建设公司哪家好

一、按键无效现象1.操作人员对机床操作时画面无反应现象M80/M800系列系统在使用键盘或触摸屏输入时&#xff0c;请勿连击键盘按键&#xff0c;输入一 次即可。键盘每向NC输入一次&#xff0c;NC系统需要计算一次&#xff0c;连续的多次重复输入&#xff0c;NC多次重复计算、显示…