运行pywinauto自动化爬公众号,出现pywinauto.findwindows.ElementNotFoundError: {'title': 'ContactListItem', 'control_type': 'Button', 'top_level_only': False, 'parent': <uia_element_info.UIAElementInfo - '微信', WeChatMainWndForPC, 66130>, 'backend': 'uia'}
需要完善代码,找到公众号按钮,公众号列表,遍历公众号列表,找到需要爬取的公众号,获取公众号文章列表窗口,获取公众号文章列表,遍历公众号文章列表,获取每篇文章的信息,获取文章详情,获取文章日期和地点,获取文章评论数、点赞数和阅读数
from imp import reload
import psutil
import pywinauto
from pywinauto.application import Application
import sys
import pickle
def DFS(win, layers):
children = []
last_layer = [win]
new_layer = []
for cnt in range(layers):
for c in last_layer:
gs = c.children()
for g in gs:
new_layer.append(g)
for x in new_layer:
children.append(x)
last_layer = new_layer
new_layer = []
return children
# 如果下面两行报错,把它们都注释掉就行了
reload(sys)
sys.setdefaultencoding('utf-8')
# 获取微信进程的PID
PID = 0
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=['pid', 'name'])
except psutil.NoSuchProcess:
pass
else:
if 'WeChat.exe' == pinfo['name']:
PID = pinfo['pid']
# 连接微信应用程序
app = Application(backend='uia').connect(process=PID)
win = app["微信"]
# 点击“公众号”按钮,进入公众号列表
gzh_btn = win.child_window(title=u'\u516c\u4f17\u53f7', control_type="Button")
gzh_btn.click()
# 获取公众号列表窗口
gzh_list_win = app['公众号']
# 获取公众号列表
gzh_list = gzh_list_win.wrapper_object().descendants(depth=4)
# 遍历公众号列表,找到需要爬取的公众号
for gzh in gzh_list:
try:
gzh_name = gzh.window_text()
if gzh_name == '丽江发布':
# 点击进入公众号
gzh.click()
break
except:
pass
# 获取公众号文章列表窗口
article_list_win = app['丽江发布']
# 获取公众号文章列表
article_list = article_list_win.wrapper_object().descendants(depth=4)
# 初始化文章列表和文章内容集合
all_articles = []
all_article_contents = set()
# 遍历公众号文章列表,获取每篇文章的信息
for article in article_list:
try:
article_info = {}
classname = article.friendly_class_name()
if (classname == "ListItem"):
# 这是一篇文章
article_title = article.window_text()
try:
print(article_title)
except:
print("Failed to print out due to emojis")
article_info["title"] = article_title
# 获取文章详情
article.click()
article_detail_win = app['文章']
article_detail = article_detail_win.wrapper_object().descendants(depth=4)
for detail in article_detail:
try:
detail_classname = detail.friendly_class_name()
if detail_classname == 'TextBlock':
# 获取文章日期和地点
detail_text = detail.window_text()
if '发布时间' in detail_text:
article_date = detail_text.split('发布时间:')[1]
article_info["date"] = article_date
elif '地点' in detail_text:
article_location = detail_text.split('地点:')[1]
article_info["location"] = article_location
elif detail_classname == 'Button':
# 获取文章评论数、点赞数和阅读数
detail_text = detail.window_text()
if '评论' in detail_text:
article_comments = detail_text.split('评论')[1]
article_info["comments"] = article_comments
elif '赞' in detail_text:
article_likes = detail_text.split('赞')[1]
article_info["likes"] = article_likes
elif '阅读' in detail_text:
article_reads = detail_text.split('阅读')[1]
article_info["reads"] = article_reads
except:
pass
# 返回文章列表
back_btn = article_detail_win.child_window(title='返回', control_type="Button")
back_btn.click()
# 将文章信息添加到列表中
all_articles.append(article_info)
all_article_contents.add(article_title)
except:
print("passed exception")
pass
# 判断是否达到循环终止条件
if 'date' in article_info and article_info['date'] > '2022年9月30日':
break
# 保存文章信息到文件中
filename = "my_articles.pkl"
with open(filename, 'wb') as f:
pickle.dump(all_articles, f)
利用gpt工具做了一些帮忙
from imp import reload
import psutil
import pywinauto
from pywinauto.application import Application
import sys
import pickle
def DFS(win, layers):
children = []
last_layer = [win]
new_layer = []
for cnt in range(layers):
for c in last_layer:
gs = c.children()
for g in gs:
new_layer.append(g)
for x in new_layer:
children.append(x)
last_layer = new_layer
new_layer = []
return children
# 如果下面两行报错,把它们都注释掉就行了
reload(sys)
sys.setdefaultencoding('utf-8')
# 获取微信进程的PID
PID = 0
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=['pid', 'name'])
except psutil.NoSuchProcess:
pass
else:
if 'WeChat.exe' == pinfo['name']:
PID = pinfo['pid']
# 连接微信应用程序
app = Application(backend='uia').connect(process=PID)
win = app["微信"]
# 点击“公众号”按钮,进入公众号列表
gzh_btn = win.child_window(title=u'\\u516c\\u4f17\\u53f7', control_type="Button")
gzh_btn.click()
# 获取公众号列表窗口
gzh_list_win = app['公众号']
# 获取公众号列表
gzh_list = gzh_list_win.wrapper_object().descendants(depth=4)
# 遍历公众号列表,找到需要爬取的公众号
for gzh in gzh_list:
try:
gzh_name = gzh.window_text()
if gzh_name == '丽江发布':
# 点击进入公众号
gzh.click()
break
except:
pass
# 获取公众号文章列表窗口
article_list_win = app['丽江发布']
# 获取公众号文章列表
article_list = article_list_win.wrapper_object().descendants(depth=4)
# 初始化文章列表和文章内容集合
all_articles = []
all_article_contents = set()
# 遍历公众号文章列表,获取每篇文章的信息
for article in article_list:
try:
article_info = {}
classname = article.friendly_class_name()
if (classname == "ListItem"):
# 这是一篇文章
article_title = article.window_text()
try:
print(article_title)
except:
print("Failed to print out due to emojis")
article_info["title"] = article_title
# 获取文章详情
article.click()
article_detail_win = app['文章']
article_detail = article_detail_win.wrapper_object().descendants(depth=4)
for detail in article_detail:
try:
detail_classname = detail.friendly_class_name()
if detail_classname == 'TextBlock':
# 获取文章日期和地点
detail_text = detail.window_text()
if '发布时间' in detail_text:
article_date = detail_text.split('发布时间:')[1]
article_info["date"] = article_date
elif '地点' in detail_text:
article_location = detail_text.split('地点:')[1]
article_info["location"] = article_location
elif detail_classname == 'Button':
# 获取文章评论数、点赞数和阅读数
detail_text = detail.window_text()
if '评论' in detail_text:
article_comments = detail_text.split('评论')[1]
article_info["comments"] = article_comments
elif '赞' in detail_text:
article_likes = detail_text.split('赞')[1]
article_info["likes"] = article_likes
elif '阅读' in detail_text:
article_reads = detail_text.split('阅读')[1]
article_info["reads"] = article_reads
except:
pass
# 返回文章列表
back_btn = article_detail_win.child_window(title='返回', control_type="Button")
back_btn.click()
# 将文章信息添加到列表中
all_articles.append(article_info)
all_article_contents.add(article_title)
except:
print("passed exception")
pass
# 判断是否达到循环终止条件
if 'date' in article_info and article_info['date'] > '2022年9月30日':
break
# 保存文章信息到文件中
filename = "my_articles.pkl"
with open(filename, 'wb') as f:
pickle.dump(all_articles, f)
根据您提供的代码,出现的错误是pywinauto.findwindows.ElementNotFoundError,它表明在查找窗口元素时找不到相应的元素。这可能是由于元素的属性或标识符发生了变化,或者元素尚未加载完成导致的。
要完善代码以找到公众号按钮和公众号列表,请尝试以下修改:
在导入模块的部分,将from imp import reload和reload(sys)注释掉。这些语句在较新的Python版本中不再需要。
在连接微信应用程序的部分,将app = Application(backend='uia').connect(process=PID)修改为app = Application(backend='uia').connect(process=PID, timeout=10)。这样可以增加连接的超时时间,以确保应用程序完全加载。
在点击"公众号"按钮之前,添加等待语句以确保窗口加载完成。可以使用gzh_list_win.wait('ready', timeout=10)来等待公众号列表窗口的加载。
在获取公众号列表的部分,修改为gzh_list = DFS(gzh_list_win, 2)。DFS函数将在指定的窗口中进行深度优先搜索,并返回指定层数的子元素列表。
pywinauto.findwindows.ElementNotFoundError错误是找不到元素的错误。检查下你定位元素的地方是否写错了或者还没有完全加载出来。可以设置一个加载等待时间,等待一定时间后再去定位元素。或者通过再程序中调试,打断点的方式运行程序,同时确认元素是否真的在界面上加载出来了。
可能是这几个原因
1没有正确安装 pywinauto 库。在使用 pywinauto 库的函数之前,请确保您已经使用 pip 命令成功安装了该库。
2没有导入 pywinauto 库。在使用 pywinauto 库的函数之前,请确保您已经在代码中使用 import pywinauto 进行了导入。
3导入了 pywinauto 库的不同版本。如果您在同一个 Python 环境中安装了多个版本的 pywinauto 库,可能会导致在执行 pywinauto 函数时找不到该函数的情况。