m0_72183621 2023-06-10 19:47 采纳率: 21.7%
浏览 85
已结题

pwwinauto调式修改

修改调式pywinauto自动化代码,原是爬朋友圈的,现在需要爬公众号的文章,标题,日期,地点,评论数,点赞,阅读
公众号举例,丽江发布
循环终止条件,日期2022年9月30日到现在
自动化每一步操作添加注释


```python

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 = 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["微信"]
# print(win.dump_tree())

pyq_btn = win.child_window(title=u'\u670b\u53cb\u5708', control_type="Button")

# cords = pyq_btn.rectangle()
# pywinauto.mouse.click(button='left', coords=(cords.left + 10, cords.top + 10))


# print(dir(pyq_win))
# print(pyq_win.dump_tree())
# print(dir( pyq_win.wrapper_object()))

all_pyq = []
all_pyq_contents = set()

filename = "mypyq_new.pkl"

last_content_cnt = 0

while True:
    # 如果按Esc关闭朋友圈页面,这里就会崩掉然后结束
    try:
        pyq_win = app['朋友圈']
    except:
        break
    try:
        pyqs = pyq_win.wrapper_object().descendants(depth=4)
        for x in pyqs:
            try:
                pyq_info = {}

                classname = x.friendly_class_name()
                if (classname == "ListItem"):
                    # 这是一条朋友圈
                    pyq_contents = x.window_text()
                    try:
                        print(pyq_contents)
                    except:
                        print("Failed to print out due to emojis")
                    if (pyq_contents in all_pyq_contents):
                        # 已经爬过这一条了
                        last_content_cnt += 1
                        continue
                    last_content_cnt = 0
                    all_pyq_contents.add(pyq_contents)
                    pyq_info["content"] = pyq_contents

                    try:
                        edits = DFS(x, 6)
                        for e in edits:
                            if (e.friendly_class_name() == "Edit"):
                                likes = e.window_text()
                                pyq_info["likes"] = likes
                            if (e.friendly_class_name() == "ListBox"):
                                pinglun = []
                                comments = e.children()
                                for com in comments:
                                    if (com.friendly_class_name() == "ListItem"):
                                        pinglun.append(com.window_text())
                                # 所有信息采集完毕
                                pyq_info["comments"] = pinglun

                    except:
                        pass
                    all_pyq.append(pyq_info)
            except:
                print("passed exception")
                pass
    except:
        pass
    # 向下滚动
    cords = pyq_win.rectangle()
    pywinauto.mouse.scroll(wheel_dist=-5, coords=(cords.left + 10, cords.bottom - 10))
    if (last_content_cnt > 20):
        break
    if (len(all_pyq) > 50000):
        break

with open(filename, 'wb') as f:
    pickle.dump(all_pyq, f)

```

  • 写回答

4条回答 默认 最新

  • 全栈若城 Python领域新星创作者 2023-06-10 21:36
    关注

    这个问题, 真是个问题啊 , 首先网页版微信不能登陆了 , 用其他的 可能会被封号 ? 谁给个思路嘞

    评论
  • Jackyin0720 2023-06-10 19:58
    关注
    from imp import reload:从 imp 模块中导入 reload 函数,用于重新加载模块并更新其导入的对象。
    import psutil:导入 psutil 模块,用于访问系统信息。
    import pywinauto:导入 pywinauto 模块,用于自动化 Windows GUI 应用程序。
    from pywinauto import Application:从 pywinauto 模块中导入 Application 类,用于创建和管理 Windows 应用程序对象。
    import sys:导入 sys 模块,用于访问 Python 解释器的系统接口。
    import pickle:导入 pickle 模块,用于序列化和反序列化 Python 对象。
    DFS(win, layers):定义一个名为 DFS 的函数,接受两个参数:一个 Windows 对象 win 和一个整数 layers。函数返回一个列表,包含从根窗口到目标窗口的路径上的所有窗口对象。
    children = []:初始化一个空列表 children,用于存储当前层的所有子窗口。
    last_layer = [win]:将根窗口对象 win 添加到列表 last_layer 中。
    new_layer = []:初始化一个空列表 new_layer,用于存储下一层中的所有窗口对象。
    for cnt in range(layers)::循环执行 layers 次,每次循环迭代变量为 cnt。
    for c in last_layer::遍历列表 last_layer 中的每个窗口对象。
    gs = c.children():获取当前窗口对象的所有子窗口对象,并将其存储在列表 gs 中。
    for g in gs::遍历列表 gs 中的每个子窗口对象。
    new_layer.append(g):将子窗口对象添加到列表 new_layer 中。
    for x in new_layer::遍历列表 new_layer 中的每个窗口对象。
    children.append(x):将窗口对象添加到列表 children 中。
    last_layer = new_layer:将列表 new_layer 中的所有窗口对象复制到列表 last_layer 中。
    new_layer = []:将列表 new_layer 初始化为空列表。
    return children:返回列表 children,其中包含从根窗口到目标窗口的路径上的所有窗口对象。
    
    评论
  • AllenGd 大数据领域优质创作者 2023-06-10 20:02
    关注
    
    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)
    
    评论
  • 夜深人静的码农 2023-06-10 20:26
    关注

    公众号和朋友圈结构完全不一样,根本调试不出来

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月11日
  • 创建了问题 6月10日

悬赏问题

  • ¥15 win11系统打开软件很慢
  • ¥30 XIAO esp32c3 读取FDC2214的数据
  • ¥20 我用malloc申请了一块空间 判空显示指针不为null 但是在输出data指针所指的地址是缺全是0 空指针不能输入值进去数组为什么呀
  • ¥15 在工控机(Ubuntu系统)上外接USB蓝牙硬件进行蓝牙通信
  • ¥15 关于PROCEDURE和FUNCTION的问题
  • ¥100 webapi的部署(标签-服务器)
  • ¥20 怎么加快手机软件内部计时的时间(关键词-日期时间)
  • ¥15 C语言除0问题的检测方法
  • ¥15 为什么四分管的内径有的是16mm有的15mm,四分不应该是12.7mm吗
  • ¥15 macos13下 ios交叉编译的问题