import psutil
from pywinauto.application import Application
import pywinauto.mouse
import sys
import time
import json
import random
import re
# 想要读取的朋友圈条数
N = 2
# 抽奖朋友圈含有的关键字
keyword = "校园跑"
# 将池大小
draw_pool_size = 30
# DFS 搜索层级
def DFS(win, layers):
children = []
last_layer = [win]
for layer in range(layers):
new_layer = []
for c in last_layer:
try:
gs = c.children()
for g in gs:
children.append((layer, g))
new_layer.append(g)
except:
pass
last_layer = new_layer
return children
# 查找指定类型控件
def query_edits(edits, classname, index):
for layer, edit in edits:
if edit.friendly_class_name() == classname and layer == index:
return edit
return None
# 查找微信进程
PID = 0
for proc in psutil.process_iter(attrs=['pid', 'name']):
if proc.info['name'] == 'WeChat.exe':
PID = proc.info['pid']
break
if PID == 0:
print("WeChat.exe 未运行或未找到进程!")
sys.exit(1)
# 连接微信
app = Application(backend='uia').connect(process=PID)
# 获取朋友圈窗口
try:
pyq_win = app['朋友圈']
except Exception as e:
print("Error when finding WeChat Moments window:", e)
sys.exit(1)
all_pyq = []
all_pyq_contents = set()
last_content_cnt = 0
print(f"开始读取前 {N} 条朋友圈:\n")
pyq_list = []
count = 0
while len(all_pyq) < N:
try:
pyqs = pyq_win.wrapper_object().descendants(depth=4)
for x in pyqs:
try:
classname = x.friendly_class_name()
if classname != "ListItem":
continue
pyq_contents = x.window_text()
if pyq_contents in all_pyq_contents:
last_content_cnt += 1
continue
last_content_cnt = 0
all_pyq_contents.add(pyq_contents)
pyq_info = {}
edits = DFS(x, 6)
sender = query_edits(edits, "Button", 3)
content = query_edits(edits, "Static", 3)
sendtime = query_edits(edits, "Static", 4)
likes = query_edits(edits, "Static", 5)
plq = query_edits(edits, "ListBox", 5)
if plq is not None:
pinglun = []
comments = plq.children()
for com in comments:
if com.friendly_class_name() == "ListItem":
pinglun.append(com.window_text())
pyq_info["comments"] = pinglun
pyq_info["sender"] = sender.window_text() if sender else "未知"
pyq_info["content"] = content.window_text() if content else ""
pyq_info["sendtime"] = sendtime.window_text(
) if sendtime else ""
pyq_info["likes"] = likes.window_text() if likes else ""
all_pyq.append(pyq_info)
# print(pyq_info)
count += 1
print(f"正在读取第{count}条朋友圈...")
pyq_list.append(pyq_info)
if len(all_pyq) >= N:
break
except:
pass
except Exception as e:
print("Error when parsing window:", e)
pass
# 自动向下滚动加载更多朋友圈
try:
cords = pyq_win.rectangle()
pywinauto.mouse.scroll(
wheel_dist=-5, coords=(cords.left + 10, cords.bottom - 10))
time.sleep(1)
if last_content_cnt > 25:
break
except Exception as e:
print("Error when scrolling:", e)
break
# print(pyq_list)
for pyq in pyq_list:
if keyword in pyq["content"]:
print("检测到抽奖朋友圈:")
print(json.dumps(pyq, ensure_ascii=False, indent=2))
likes_str = pyq.get("likes", "")
likes_list = [name.strip()
for name in re.split('[,,]', likes_str) if name.strip()]
# 前n名
top_likers = likes_list[:draw_pool_size]
print("抽奖候选名单:")
for i, name in enumerate(top_likers, 1):
print(f"{i}. {name}")
winner = random.choice(top_likers)
print(f"\n中奖:{winner}")