Python+uiautomator2实现朋友圈自动点赞评论:控件定位与ADB实战
2026/8/31 3:41:38 网站建设 项目流程

简介:这是一套面向Python初学者与微信运营人员的自动化工具源码,旨在解决日常朋友圈高频互动耗时耗力的问题,适用于客户关系维护、私域流量运营及轻量级微信营销场景。资源共118个文件,包含5个核心Python脚本(如config.py参数配置、run.py主控流程)、4个JavaScript前端交互文件、100张PNG评论配图资源、1个NSIS安装脚本、1个ICO图标及CSS/HTML等配套文件,整体压缩包仅1.2MB,结构清晰、模块分工明确。已有969人学习下载,读者可直接复用完整自动化逻辑,掌握基于PyAutoGUI或类似库实现微信界面识别与模拟操作的技术路径,并获得含中断机制(长按Shift键终止)、微信登录状态校验、图片评论素材集成等实用设计细节。

2. 社交自动化的“老问题”:为什么手动点赞也能成为项目

朋友圈点赞这件事,表面上看就是个“动动手指”的轻操作,但如果你负责运营一个品牌形象号、帮家里长辈打理账号,或者单纯是个每天被几十条动态刷屏的重度用户,你会发现这动作积累起来非常烦人。更关键的是,点赞和评论在微信的社交推荐机制里属于“互动信号”,定期维护能明显提升你和好友之间的曝光权重,但不维护又不行。

于是很多人会想:能不能让 Python 帮我自动处理?这个项目标题背后的核心需求,其实不是“自动点赞”本身,而是把重复的社交维护动作脚本化,让我在每天固定的时间点,用一段代码完成朋友圈的浏览、点赞、选择性评论,全程不需要打开微信。适合做这件事的人有两类:一是 Python 基础过关、想拿真实项目练手的开发者,二是有轻度社交维护需求、又不想触碰外挂红线的个人用户。

需要先说清楚的是,微信官方对自动化操作是严格限制的,所以这类工具的正确打开方式是“个人学习 + 低频率辅助”,而不是批量营销。我下面提供的设计思路和源码,是基于 Android 调试桥(ADB)+ UI 自动化框架实现的,本质上是模拟人手在屏幕上的点击和滑动,不涉及任何协议破解和注入式外挂。只要把频率控制在合理范围,它就是一个非常典型的Python GUI 自动化 + 控件定位实战案例。

2. 内容整体设计与思路拆解

2.1 为什么不用 pyautogui 图像识别,而选控件定位

朋友圈自动化最核心的技术选型就是“怎么告诉程序该点哪里”。早些年大家习惯用 pyautogui 做纯图像识别,截屏后找点赞图标的坐标,但这条路线在现代微信版本里已经走不通了。原因很简单:朋友圈的列表是动态加载的,每个好友的头像、昵称、配图位置都不固定,加上不同手机的屏幕分辨率不一样,同一张截图在不同设备上识别出来的坐标可能是偏移的。你换一台手机,或者朋友圈里多了一张九宫格图片,坐标就全部作废了。

我的选择是uiautomator2,这是一个基于 Android UiAutomator 的 Python 库,它可以直接读取当前界面上的控件树,把“点赞”按钮、评论输入框、头像、文本内容全部解析成带属性的节点。这样程序就能用“找到文本为‘赞’的控件,然后点击它的中心点”这种逻辑来操作,跟屏幕分辨率完全解耦。对比一下就很直观:

方案原理稳定性跨设备能力学习成本
pyautogui 图像识别截图 + 模板匹配差,分辨率一变就废
uiautomator2 控件定位读取原生控件树好,同版本微信通用
Appium 全功能框架控件定位 + 多端支持最好,但臃肿

Appium 其实也能做,但它是个重型框架,要起 server、配置 Desired Capabilities,对朋友圈这种单页面任务来说有点杀鸡用牛刀。uiautomator2 直接通过 Python 调用设备上的 ATX agent,轻量且容易调试,是这个场景下性价比最高的方案。

2.2 功能边界划分:哪些该自动化,哪些必须留手动

项目设计的第一步不是写代码,而是先画清楚“自动化的边界”。我的做法是把朋友圈互动拆成三个等级:

第一级是纯浏览,也就是模拟手指滑动屏幕,逐条刷过好友动态,这个完全交给程序,没有任何风险。第二级是点赞,这个也适合自动化,但要注意的是微信对短时间内的点赞频率有隐性风控,连续点五六十个赞很容易触发异常检测。第三级是评论,这是风险最高的一环,因为评论是可见文本,如果内容重复或者措辞生硬,好友一眼就能看出来是机器操作,轻则尴尬,重则被举报。

所以我的源码设计原则是这样的:浏览和点赞走全自动,但评论必须走“半自动”。程序会把符合条件的动态筛选出来,从内置的评论库里随机挑一条,先推送到手机通知栏让我确认,我点确认它才真正发送。这样既保留了自动化的效率,又守住了“评论内容可见”这条底线,不会给好友留下批量操作的印象。

2.3 目录结构与模块划分

为了让代码可维护,我没有把所有逻辑堆在一个 Python 文件里,而是拆成了四个模块:

wechat_moments_bot/ ├── config.py # 配置文件:目标好友名单、评论库、时间间隔 ├── monitor.py # 朋友圈监控模块:检测新动态、过滤已处理项 ├── actions.py # 核心动作模块:滑动、点赞、评论、返回 ├── main.py # 入口脚本:调度监控与动作模块 └── data/ └── replied.db # SQLite 数据库,记录已互动过的动态ID

config.py 管所有可变参数,比如每天运行时间段、每条动态之间的间隔、评论关键词黑名单,这些全部抽出来,这样换设备或者调整策略的时候不用改主逻辑代码。data/replied.db 是个轻量 SQLite 数据库,用于记录哪些动态已经处理过,防止程序在同一个时间段内重复点赞或重复评论。这个设计很关键,因为朋友圈的列表是滚动的,如果不做去重,程序滑回去的时候就会再次碰到同一条动态,造成二次点赞,这在实际使用中非常容易被好友发现。

3. 环境准备与核心依赖解析

3.1 Python 环境与依赖安装

这个项目对 Python 版本没有特殊要求,3.8 以上就行。我建议直接用 venv 建一个干净的虚拟环境,避免和系统 Python 包冲突。需要安装的依赖只有三个:

pip install uiautomator2 pip install weditor pip install sqlite3-utils

sqlite3 本身是标准库,不需要装,但如果你习惯用 sqlite3-utils 这种命令行工具来快速查看数据库内容,可以顺手装一下,排查去重问题时特别方便。

安装完 uiautomator2 后,先把手机用 USB 线连上电脑,打开开发者选项里的 USB 调试,然后执行:

python -m uiautomator2 init

这条命令会在手机端安装 ATX agent 相关服务。初始化完成后,用python -m uiautomator2 install检查一下连接,如果输出设备序列号和安卓版本,说明环境已经通了。

3.2 使用 weditor 快速定位朋友圈控件

新手最容易卡住的地方是不知道“点赞”按钮在控件树里长什么样。这里推荐用 weditor,它是 uiautomator2 配套的网页版控件检查器。在手机连着电脑的情况下,终端运行:

python -m weditor

浏览器会自动打开一个页面,左侧显示手机实时屏幕,右侧显示控件层级树。手动打开微信朋友圈,点击屏幕上的点赞按钮,右侧会高亮对应的控件,你能看到它的 resource-id、text、className 等属性。

朋友圈因为是在 WebView 里渲染的,所以控件属性跟原生 App 不太一样。我的实测经验是,点赞按钮的 text 属性通常就是“赞”,评论按钮的 text 是“评论”,虽然它们都被嵌套在 WebView 的容器里,但 uiautomator2 依然可以通过 text 属性直接定位到。如果某台机器上 text 属性解析失败,备选方案是用bounds属性里的坐标百分比来点击,但这是下策,能做控件定位就优先控件定位。

4. 核心源码实现与关键逻辑解读

4.1 朋友圈入口判断与异常保护

打开朋友圈的第一步是确保微信处于未解锁的前台状态。我的 main.py 里写了这样一个函数:

import uiautomator2 as u2 import time def open_moments(d): # 先回到桌面,再冷启动微信,避免从后台恢复时界面状态不一致 d.press("home") time.sleep(1) d.app_start("com.tencent.mm") time.sleep(3) # 点底部“发现”Tab d(text="发现").click() time.sleep(1) # 点“朋友圈”入口 d(text="朋友圈").click() time.sleep(2) # 判断是否真正进入朋友圈页面,用标题栏的“朋友圈”文本做锚点 if not d(text="朋友圈").exists(timeout=5): raise RuntimeError("朋友圈页面打开失败,请检查微信是否登录")

这段代码有几个细节值得说明。用d.press("home")先回桌面,是为了保证微信是冷启动,而不是从后台恢复,因为后台恢复时界面可能是聊天列表,也有可能是小程序页面,状态不可控。判断是否进入朋友圈用的是页面标题文本,这个锚点比判断列表控件更可靠。timeout=5参数很关键,如果 5 秒内没出现预期控件,程序直接抛异常,避免后续点击落空导致整个流程失控。

4.2 滑动浏览与动态去重逻辑

朋友圈的数据是懒加载的,必须通过滑动触发加载更多。但是滑动过快会导致画面卡顿,控件树解析不完整,滑动过慢又会影响效率。经过反复调试,我用的参数是每次滑动屏幕高度的 60%,间隔 1.5 秒到 2.5 秒随机化:

import random def scroll_and_collect(d, max_scrolls=30): seen_ids = set() # 使用数据库记录已处理的动态ID conn = sqlite3.connect("data/replied.db") for i in range(max_scrolls): # 获取当前屏幕上的所有动态节点 items = d.xpath('//android.webkit.WebView//android.view.View[@content-desc]') for item in items.all(): desc = item.attrib.get("content-desc", "") # 朋友圈动态的 content-desc 通常包含作者和文本摘要 if desc and len(desc) > 5: moment_id = hash(desc) # 用内容哈希做动态ID,不依赖微信内部标识 if moment_id not in seen_ids and not is_processed(conn, moment_id): seen_ids.add(moment_id) process_moment(d, item, moment_id, conn) # 屏幕向上滑动60% d.swipe(0.5, 0.75, 0.5, 0.15, duration=0.2) time.sleep(random.uniform(1.5, 2.5))

这里用了content-desc属性来识别动态内容。微信朋友圈在 WebView 里渲染时,每条动态都会有一个 content-desc 描述,里面拼接了作者昵称和文本内容,这正好可以作为动态的唯一标识。用hash(desc)生成动态 ID 的好处是不需要依赖微信内部的任何接口,纯前端就能实现去重。

4.3 点赞操作的三种按钮状态识别

朋友圈点赞按钮有一个经典的“状态变化”问题:如果一条动态已经被你点过赞,按钮显示的是“取消赞”,如果没点过,显示的是“赞”。这看似简单,但自动化执行时如果没判断清楚,会出现“想点赞反而取消了赞”的尴尬情况。

我的处理方式是先点赞、再验证、错了就回滚:

def tap_like(d): # 优先找“赞”文本,找不到再找“取消赞” like_btn = None if d(text="赞").exists(timeout=2): like_btn = d(text="赞") elif d(text="取消赞").exists(timeout=2): # 已经是已赞状态,跳过 return False if like_btn: like_btn.click() time.sleep(1) # 点击后立刻校验是否变成了“取消赞”,是则说明点赞成功 if d(text="取消赞").exists(timeout=2): return True return False

这段逻辑虽然简单,但很实用。点击后立刻验证按钮状态变化,等于给操作加了一层保险,比单纯“点了就算成功”要可靠得多。实测中,因为网络延迟或控件树刷新不及时,偶尔会出现点击后无反应的情况,这时候就不能继续往下走了,要重试两三次,重试还失败就跳过这条动态,不要死磕。

4.4 评论的半自动确认机制

评论是我处理的“红线区”,代码上严格走半自动。程序不会直接把评论发出去,而是先把内容弹到通知栏,等我自己确认:

def smart_comment(d, moment_item, comment_pool): # 从评论库里随机选一条,避免总是重复同样的话 content = random.choice(comment_pool) # 点开评论输入框 d(text="评论").click() time.sleep(1) # 输入内容 d.send_keys(content, clear=True) time.sleep(0.5) # 弹通知栏让用户确认 d.open_notification() d(text="确认发送评论").click() # 点击发送 d(text="发送").click() time.sleep(1) d.press("back")

评论库的内容建议自己维护,比如“拍得真好”“学习了”“这个角度绝了”这类通用短句。但这里有个很重要的经验:评论库的文案风格最好贴近你自己的说话习惯。如果你平时在朋友圈从来不说“哈哈笑死”,那自动评论里就不该出现这种词,否则好友一眼看穿。

4.5 频率控制与随机延时策略

自动化的核心不是“快”,而是“像人”。微信的风控系统对操作频率非常敏感,如果你 10 秒内连续点赞 30 条动态,账号被限制朋友圈功能的风险极高。我的经验是把每次互动之间的间隔控制在8 到 15 秒,并且用随机数打乱,而不是固定一个值:

def random_delay(): base = random.uniform(6, 10) # 每执行10次操作后,额外休息20-30秒,模拟看手机休息的过程 if random.random() < 0.1: time.sleep(random.uniform(20, 30)) else: time.sleep(base)

间隔的随机化很讲究。如果你用固定 8 秒,程序会呈现非常规律的周期性操作,这在服务端眼里反而更明显。我用的是均匀分布 + 概率性长休息的策略,更贴近真实用户的间歇性使用习惯。另外,每次运行的总时长控制也很有必要,我建议单次运行不要超过 15 分钟,超过就自动退出,第二天再跑,给账号留足休息时间。

5. 常见问题与排查技巧实录

5.1 控件定位失败的排查思路

这个项目在使用中最常遇到的问题就是“明明手机上能看到点赞按钮,但程序就是找不到”。我从原理上排查过这个问题,总结出三个层次的原因:

第一层是WebView 渲染延迟。朋友圈内容是在 WebView 里异步加载的,先出现布局框架,再填充文本内容,所以控件树里存在“有按钮但 text 属性还是空”的中间状态。解决办法是不要一进页面就开始滑动,先time.sleep(3)等首屏加载完整,并且每次滑动后也等待 1 秒,让新内容完成渲染。

第二层是控件树里的文本被截断。微信在某些场景下会把“赞”“评论”这类短文本放进 content-desc 而不是 text 属性,这在 weditor 里能看到区别。如果发现用 text 定位不到,可以改用 XPath 匹配 content-desc 包含“赞”的节点,语法像这样:

d.xpath('//*[contains(@content-desc, "赞")]')

第三层是弹窗遮挡。新版本微信偶尔会弹出“朋友的新动态”提示条,或者青少年模式引导,这些透明浮层会覆盖在朋友圈列表上方,导致点击坐标偏移。我在 main.py 里加了一个简单的弹窗检查函数,每进入朋友圈前先尝试点掉所有已知的关闭按钮:

def close_popups(d): for text in ["关闭", "我知道了", "以后再说", "跳过"]: if d(text=text).exists(timeout=1): d(text=text).click() time.sleep(0.5)

5.2 账号风控风险的避坑经验

关于风控,我必须多说几句。有些朋友拿到代码后喜欢把间隔时间改成 1 秒,觉得这样效率高,这其实是拿账号在冒险。微信对朋友圈互动有一套多维度的风控体系,不仅看频率,还看操作路径的合理性。真实用户不会连续给十个不相关的好友点赞,更不会在凌晨三点突然开始大量互动。

我给这个项目定的使用纪律是:单次运行最多处理 30 条动态,每天运行一到两次,间隔尽量安排在上午和傍晚的活跃时段。另外,朋友圈的内容五花八门,不适合所有动态都点赞。现实中我们也不会给每条广告、每条转发都点赞,所以我在 config.py 里维护了一个“不互动关键词”列表,比如“点赞抽奖”“拼多多”“转发领取”,命中这些关键词的动态直接跳过。这个设计非常必要,因为给广告点赞不会增加友情,只会让好友觉得你是个机器人。

5.3 常见问题速查表

问题表现可能原因解决方案
打开朋友圈后找不到任何控件WebView 未加载完成或页面卡在启动页增加等待时间到 5 秒以上,检查是否被弹窗遮挡
点赞后按钮没有变成“取消赞”点击坐标偏移或网络延迟重试 2-3 次,仍失败则跳过该动态
程序滑动速度太快,列表加载不全滑动间隔太短将滑动后等待时间调整为 1.5-2.5 秒
评论内容发送失败输入框内容没有清空或输入法干扰使用clear=True参数,检查输入法是否是系统默认
数据库去重失效,重复点赞content-desc 中有动态时间导致哈希变化先正则提取掉时间字段再生成哈希值

5.4 从单个点赞到工具链的扩展思路

做完了点赞评论,你会发现这套架构可以复用到很多微信自动化场景。比如,朋友圈监控加上微信的通知监听,可以实现“特别关心的人发动态时第一时间提醒我”;把 actions.py 里的点赞函数换成收藏函数,就是一个自动收藏工具;或者结合定时任务库(schedule 或 APScheduler),把 main.py 注册成每天上午九点自动运行的定时任务,真正做到无人值守。

我自己的实际做法是,在服务器上部署了一个空闲的安卓模拟器,用 cron 定时拉取这些代码运行。模拟器通过 ADB 连接宿主机,跟真实手机的 API 完全一致,这样既不影响日常用手机,又能让脚本在固定时间执行。不过模拟器的控件树和真机在某些细节上有差异,首次适配时需要在 weditor 里重新确认一遍控件属性,这个工作量不大,但逃不掉。

6. Python 核心函数复习:random 模块的使用细节

这个项目里到处都用到了 random 模块,其实它是整段代码里对“避免机械化”贡献最大的标准库。很多人只会在代码开头写一句import random,然后就在需要随机数的地方用random.randint,但我建议你用的时候多想一想:你到底需要什么样的随机分布?

举个例子,random.uniform(6, 10)生成的数字在 6 到 10 之间均匀分布,也就是说 6.1 和 9.9 出现的概率一样。但真实用户的操作间隔并不会这么均匀,短间隔出现的频率更高,偶尔才会出现一次长时间停顿。如果你想让模拟更像真人,可以用random.expovariate生成指数分布的间隔,这种分布的特点是大量数值集中在较短区间,偶尔出现极长值,更符合人“大多数时候快速连续操作,偶尔停下看看内容”的行为特征。

但这也不绝对。经过我自己的对比测试,均匀分布配合 10% 概率的长休息,在朋友圈场景下表现已经足够自然,复杂的分布反而可能让总运行时间超出预期。所以我的建议是:先用 uniform 跑通流程,再根据你账号的实际反馈微调。这个“先跑通,再优化”的思路适用于所有自动化项目。

另外,random 模块的随机数默认是伪随机,如果在程序启动时没有给random.seed()设置种子,每次运行的行为就不同,这对我们反而是好事,因为它进一步增加了操作序列的多样性。但如果你要复现某个时间段的操作记录用于调试,就需要设置固定种子,这属于进阶用法,大家按需使用即可。

7. 合规边界与个人使用建议

最后必须强调一下合规问题。虽然这个项目技术上实现的只是 ADB 模拟点击,但任何自动化操作微信的行为都违反了微信的用户协议。我不建议任何人把它用于以下场景:批量给陌生人点赞引流、替他人代挂账号操作、以营利为目的的营销刷量。这些行为轻则账号被封禁,重则可能涉及法律纠纷,实在不值得。

适合使用这个项目的场景只有一个:管理你自己的个人账号,在低频、低量、克制的前提下,把每天必须做的社交维护动作自动化。我把它定位成“个人效率工具”,而不是“营销外挂”,从设计到代码实现都围绕这个定位展开。如果你只是想学习 Python 的 UI 自动化技术,这个项目也很合适,因为你可以在完全不动微信的情况下,用同样的代码结构去操作任何其他 App。

在合规方面,我还想分享一个经验:控制操作量比控制操作频率更重要。一套运行了半年的脚本,如果某天突然把间隔缩短了,它会在行为痕迹上与以往完全不同,这在风控系统眼里比“操作量略大”更可疑。所以请给你的脚本定一套稳定的运行参数,不要频繁调整,长期稳定运行才是安全的关键。

我在自己项目中使用的参数是:每天运行一次,每次浏览 30 条左右动态,点赞不超过 10 个,评论不超过 3 条,全程间隔 8 秒以上。这个量级运行了几个月,没有出现过任何异常提醒。把预期放低一点,细水长流,这类工具才能在边界内长期发挥价值。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询