pywinauto定位找不到

运行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 函数时找不到该函数的情况。