ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Playwright+Chrome140:Telegram账号自动化实战指南

Playwright+Chrome140:Telegram账号自动化实战指南 这阵子一直在折腾一个事情把 Telegram 账号的日常重复操作全部交给基于 Chrome140 的自动化脚本去跑。起因很简单我手里几个账号需要定时处理消息、归档素材、统计数据每天点来点去实在是浪费时间于是决定干脆写一套自动化流程第一篇文章先把需求和环境讲清楚。如果你也想做类似的账号自动化或者单纯对浏览器自动化感兴趣这一篇能帮你少走不少弯路。先说清楚这个系列要做什么。整个项目围绕 Telegram Web 端的账号操作展开技术底座是 Python Playwright目标浏览器锁定在 Chrome140。为什么选 Chrome140 而不是用最新版后面会专门讲。这篇是第一篇核心只有两件事需求分析、环境搭建。把这两块地基打牢后面的脚本开发、登录态保持、批量操作才有得谈。1. 把账号自动化这五个字先拆开看1.1 你真正需要自动化的是哪些操作做自动化之前一定要先问自己到底哪些操作在消耗我的时间我最初的想法很模糊就是感觉 Telegram 很多操作很烦。后来把日常动作列了个清单才看清楚问题在哪。常见的高频操作包括定时向群组或频道发送公告、统计某个时间段内成员的发言量、把新加入的联系人信息归档到表格、对指定消息做批量转发或回复以及定期清理已读会话。列完清单之后事情就明朗了这些操作有一个共同特征它们不依赖复杂的业务判断只需要按固定规则执行而且出错之后可以靠重试解决。这就是最适合自动化的场景。反过来如果你的需求是根据聊天内容理解用户情绪并做出个性化回复那就不应该走浏览器自动化这条路而是应该考虑官方 Bot API 甚至接入大模型去处理。我的建议是把需求清单里的每一项标记三个属性频率每天/每周/偶尔、稳定度是否总是同样的流程、风险度是否涉及敏感操作。频率高、稳定度高、风险度低的三项优先做。我自己最终圈定的第一优先级是定时消息发送和成员发言统计这两个需求最机械、最耗时间也最容易验证自动化的效果。1.2 为什么先做 Web 端而不是客户端或官方 API明确了要自动化哪些操作之后紧接着面对一个选型问题用官方 Bot API、桌面客户端自动化还是 Web 端浏览器自动化先说官方 API。Telegram 的 Bot API 功能其实很强能发消息、管理群组、收发文件。但它的限制非常明显Bot 不是账号它无法替代你的个人账号去做查看私人会话以自己的身份发言访问只有账号才能看到的群列表这类操作。如果你需要的是账号粒度的操作纯 Bot API 满足不了。桌面客户端自动化也有问题。Telegram 桌面版基于 Qt跨平台界面的控件树在 Windows、macOS、Linux 上差异很大做 UI 自动化时定位元素极度痛苦。而且桌面客户端为了保护用户输入很多控件是自绘的自动化框架根本读不到文本内容。这就只剩 Web 端了。Telegram Web 是一个完整的 SPA单页应用页面结构清晰所有 DOM 元素都能被浏览器自动化框架正常访问。这意味着我们能用最成熟的浏览器自动化技术栈——Playwright 或者 Selenium——去操作它。再加上 Web 端不需要额外安装客户端只要 Chrome 能打开网页脚本就能运行部署成本也是最低的。1.3 自动化项目一定要提前划清边界这里我要强调一个容易踩的坑账号自动化项目如果边界不清会变成无底洞。我见过有人想做一个全自动运营系统需求列了二十多条最后卡在登录验证环节几个月都没跑通。所谓边界一句话总结就是不做任何对抗平台风控的事情。具体来说不搞批量注册、不搞协议群发、不用自动化去刷消息或操纵数据。这有几层考虑。第一层是合规任何自动化操作都应该遵守目标平台的服务条款这是底线。第二层是成本一旦触发风控导致账号受限你辛辛苦苦搭的整个系统就全废了得不偿失。第三层是效率绕过风控需要维护的成本极高而且永远是猫鼠游戏精力投入没有尽头。所以我在这个项目里给自己的边界是只操作自有账号、只做常规运营动作、运行频率控制在对正常用户无害的水平。这个边界后面写脚本的时候会反复用到它决定了代码里哪些地方要加延时、哪些操作要避免、哪些流程要设计成半自动而不是全自动。2. Chrome140 做自动化底座的三个现实理由2.1 版本锁定让调试和部署都可预期选 Chrome140不是因为它是最新版本恰恰相反是因为我们可以把它锁定为一个稳定基线。浏览器自动化的痛点之一就是版本漂移浏览器一升级底层调试协议可能就变了运行得好好的脚本突然全部失效。Chrome 的版本节奏很快大版本号大概每四到六周就会跳一次。如果脚本不做任何锁定今天跑在 Chrome138下个月变成 Chrome142某个 API 的行为变了你的脚本可能就挂在某个查找元素的步骤上。这个问题在 CI 环境或者服务器上部署时特别明显因为你无法保证生产环境的浏览器永远不升级。所以在项目一开始就锁定Chrome140 匹配的驱动 适配的自动化框架这套组合相当于给整个项目画了一个稳定的靶子。我在本地环境、测试环境和将来的部署环境统一安装 Chrome140并且关闭浏览器的自动更新。这样调试期间遇到的所有问题都只针对这一个环境去定位不会出现本地能跑服务器上挂了但不知道是版本导致的这种玄学问题。2.2 Chrome140 对自动化协议的兼容性足够稳浏览器自动化底层依赖的是 Chrome DevTools ProtocolCDP。Playwright 足够聪明它会根据浏览器的版本自动调整 CDP 调用方式但这种自适应也不是无限制的它有自己支持的浏览器版本范围。锁定 Chrome140是因为它对现有的自动化框架和协议支持非常稳定既不老到缺特性也不新到可能有隐藏变化。做浏览器自动化不是追新而是求稳。你把一个跑在生产环境的自动化脚本升级到最新版浏览器通常不会获得新功能只会承担长尾兼容性的风险。Chrome140 这个版本本身已经不是最早期的版本了各种 CDP 行为经过多个版本的打磨已经处于稳定窗口期。对于我们要做的 DOM 操作、点击、输入、截图、保存 Cookie 这些常规动作它全部支持得非常好实际跑下来几乎不需要做任何版本相关的 hack。2.3 Web 端在自动化探测层面天然友好没有人愿意自己的账号因为自动化操作被限制所以选型时要考虑探测友好性。相比桌面客户端和第三方协议客户端Web 端有两个天然优势。第一Web 页面的一切操作都发生在一个普通浏览器进程里对于服务器来说这就只是一个正常用户在访问网页没有特殊的协议特征。第二现代浏览器对 Web 自动化框架有完善的远程调试支持这意味着脚本可以正常模拟鼠标移动、键盘输入事件分发链路和真实用户几乎完全一致。我这么说不是为了鼓励绕过任何限制而是想表达如果你要做合规的账号操作Web 端是技术风险最小、后面脚本最不容易出诡异问题的选择。总有人说要用注入方式直接调接口但那样做等于把账号的每次访问都变成了可疑的协议行为从账号安全角度反而是更大的隐患。浏览器自动化是基于正常网页交互的技术路径只要控制在合理频率是稳妥且可持续的。3. 自动化方案选型为什么最终选了 Playwright3.1 三个主流方案的核心差异对比这个项目考虑过三条技术路线Selenium、Playwright、以及 RPA 工具比如影刀这类。先给一张对比表把我实测下来的感受整理清楚。方案定位元素定位能力等待机制状态保存上手成本Selenium老牌 Web 自动化强但 API 偏旧手动显式等待为主需自行处理 Cookie中Playwright现代 Web 自动化强自带自动等待自动等待非常省心内置 storage_state低影刀等 RPA通用桌面/网页自动化依赖界面录制按录制配置执行不擅长精细状态管理低但定制性差从表里能看出来Selenium 最大的问题是它需要你自己写大量等待逻辑。Web 页面加载是异步的元素出现的时间不确定Selenium 里经典的findElement如果没加等待很容易报元素找不到。你得手动写WebDriverWait这种代码一套流程里等待逻辑占了三分之一代码又臭又长。RPA 工具适合一个完全不懂编程的人去快速录一个流程但做 Telegram 这种复杂 SPA 的精细化自动化RPA 的录制回放思路会遇到麻烦页面结构一旦有一点点变化录制好的坐标点击就全部错位。而且 RPA 对浏览器内状态的掌控不够细想做到检测某条消息是否出现再决定下一步这种逻辑写起来很别扭。Playwright 在这三个方案里最吸引我的是它的自动等待机制和状态保存能力。前者帮你消掉了大量等待代码后者让登录一次之后保持登录态变得极其简单。这两个特性恰好是账号自动化项目最痛的两个地方。3.2 Playwright 的自动等待机制到底省了多少事Playwright 的自动等待机制简单来说就是当你调用click()或者fill()时它不会立刻执行操作而是先不断轮询检查目标元素是否可操作可见、稳定、不被遮挡、已附加到 DOM满足条件后才真正执行。这一套行为是框架内置的不需要你在代码里写任何 sleep 或者显式等待。我实际对比过用 Selenium 写同一个登录流程大概要写十行左右的等待代码穿插在每一步操作之间。用 Playwright这十行全部删除代码直接从打开页面 → 填表 → 点击登录 → 检查跳转一路写到底简洁程度完全是两个量级。有人可能会担心自动等待会不会让脚本变慢我的实测结果是大多数情况下 Playwright 的自动等待比手动 sleep 更快。因为手动 sleep 通常是保守地多等等比如固定等 2 秒Playwright 是在元素真的可操作的那一瞬间就继续执行可能只要 0.3 秒。它看起来是在等实际上是在用轮询换效率整体流程通常比带固定延时的脚本更高效。3.3 什么场景下我会退回去直接操作 CDPPlaywright 虽然强但它不是万能的。从架构上看Playwright 是对 CDP 的高层包装你做日常操作完全不需要关心底层细节。但在某些调试场景里我建议直接绕过 Playwright用 CDP 去定位问题。比如你发现某个点击操作在 Playwright 里一直超时但手工用 Chrome 开发者工具操作却没问题。这种时候我一般会直接用 Chrome DevTools 的远程调试接口手动发送 CDP 命令去看控制台输出、网络请求和 DOM 状态定位到底是元素真的不存在还是元素存在但 Playwright 认为它不可操作。再比如你想观察页面发出的所有 WebSocket 消息Playwright 默认不暴露这一层但 CDP 的 Network 域里有完整的 WebSocket 帧记录。我在开发早期的确会偶尔开 Remote Debugging 看一眼底层行为确认 Telegram Web 的实时通信机制。这不属于日常开发必需但你知道有这条退路遇到诡异问题时排查思路会宽很多。4. 环境搭建全流程从 Python 到浏览器驱动4.1 整个环境的组成清单开始动手之前先把环境清单列出来。这个项目需要的核心组件不多一个 Python 运行环境建议 3.10 及以上、Chrome140 浏览器本体、Playwright 库、以及系统安装时可能需要的依赖库。如果你在 Linux 服务器上部署还需要考虑字体和系统库的缺失问题这一块后面专门说。为什么需要 Python 3.10 以上Playwright 的新版本对 Python 版本有最低要求太老的 Python 装不上最新版本的依赖。而且 3.10 之后 Python 的语法特性对异步编程支持更好Playwright 的异步 API 写起来更顺手。如果你机器上之前装了老版本 Python建议先确认一下python3 --version的输出结果。搭环境的第一件事永远是确认基础版本别等代码跑起来报语法错误了才回头查。4.2 用虚拟环境隔离依赖这一步是最容易被跳过的但我强烈建议你不要跳过。用虚拟环境venv把项目的依赖和其他 Python 项目的依赖隔离开可以避免不同项目之间的版本冲突。mkdir telegram-auto cd telegram-auto python3 -m venv .venv source .venv/bin/activateWindows 上激活命令稍有不同.venv\Scripts\activate。激活之后命令行提示符前面应该会出现(.venv)前缀这表示你已经进入了隔离环境。这一步做完之后所有 pip 安装的包都只存在于这个项目的 .venv 目录里不会污染全局的 Python 环境。我在这个项目里还习惯把requirements.txt固定下来。你不需要把所有依赖的最新版本都记下来而是记录你验证过可用的那个版本。比如playwright1.53.0这样写死。这不是 Windows 观念这是生产环境的基本素养——版本不锁定后面任何人想复现你的环境都会默默踩坑。4.3 安装 Playwright 并准备 Chrome140激活虚拟环境之后安装 Playwright 相当直接pip install playwright这里有一点要特别注意Playwright 默认有自己编译的 Chromium 浏览器和系统安装的 Chrome 是不同的东西。Playwright 自带的 Chromium 通常比系统 Chrome 版本更新。在本项目中我们明确要以 Chrome140 为基线所以不要用playwright install chromium去拉它自带的浏览器而是让 Playwright 直接使用系统里已经装好的 Chrome。用法是启动浏览器时指定channelchrome。这样 Playwright 就会去系统路径找 Chrome 可执行文件。你要做的就是确保系统安装的 Chrome 版本是 140。版本验证方法是在地址栏输入chrome://version/查看命令行下也可以通过 Chrome 的--version参数输出。如果你是在 Linux 服务器上部署比如 Ubuntu那么装完 Chrome140 之后还需要安装一堆系统运行库。Playwright 提供了一个内置命令帮你搞定大部分playwright install-deps chrome这个命令会自动安装 Chrome 运行所需的系统依赖库省得你手动一条条去对。我在 Ubuntu 上实测过如果不跑这一步脚本运行到打开浏览器的那一步通常会提示缺少 libnss3 之类的库非常劝退。4.4 第一个验证脚本确认环境能跑通环境装好之后不要急着写业务代码先跑一个最小的脚本验证链路是通的。这个脚本做的事情很简单打开 Chrome140、访问一个页面、打印标题、然后关闭。from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch( channelchrome, headlessFalse, ) page browser.new_page() page.goto(https://example.com) print(页面标题:, page.title()) browser.close()跑这个脚本时你会看到 Chrome 窗口自动打开然后关闭命令行打印出页面标题。如果这一步成功说明 Playwright 能正确调起 Chrome140、建立通信链路、执行页面访问和读取操作。整个环境搭建的基础动作就全部验证通过了。我个人建议把headlessFalse有头模式保留至少在开发阶段保留。因为无头模式下你完全看不到浏览器发生了什么定位问题时非常痛苦。等脚本稳定了再切到headlessTrue做无人值守运行。4.5 环境搭建阶段的常见报错和解决办法环境搭建看似简单实际跑起来会遇到不少报错。我把自己踩过的坑和解决方案整理成表格方便你对照排查。报错现象根本原因解决办法Executable doesnt exist没装系统 Chrome 或路径找不到确认 Chrome140 安装完成检查chrome://version可用缺少libnss3.so等动态库Linux 系统库缺失执行playwright install-deps chromeERROR: Browser closed unexpectedly浏览器启动时崩溃用有头模式启动查看是否有对话框弹出检查系统资源端口占用导致远程调试失败多个脚本同时跑共享调试端口给每个实例指定独立的调试端口或使用异步上下文脚本报编码错误Windows 控制台默认编码问题Python 代码文件头加# -*- coding: utf-8 -*-或者在运行时设置环境变量除了表格里的这些还有一个很隐蔽的坑在 Linux 服务器上如果以 root 身份运行 Chrome需要加上--no-sandbox参数否则 Chrome 会拒绝启动。这个参数可以直接传给 Playwright 的 launch 方法browser p.chromium.launch( channelchrome, headlessTrue, args[--no-sandbox], )不过要提醒一句--no-sandbox会降低浏览器进程隔离的安全性只用于你完全信任代码的部署环境。本地开发就不用纠结这个程序员模式下加不加都行生产环境做好权限管理再考虑。5. 登录态是账号自动化的第一道门槛5.1 登录流程用什么方式走Telegram Web 的登录主要有两种方式扫码登录和手机号加验证码。自动化脚本里我推荐优先做扫码登录。原因很简单验证码登录还需要接收短信而扫码只需要你用手机 Telegram 扫一下本质是手机确认授权不依赖短信通道的稳定性。写登录脚本时不要试图去绕过验证码或者做任何对抗性操作老老实实走正常登录流程。脚本帮你打开页面、把二维码区域显示出来然后暂停等待人工扫码。这一步做成半自动是最合理的人工扫码是一次性动作扫完之后登录态会被保存下来后面所有自动化操作都基于这个已登录的上下文不再需要重新扫。5.2 用 storage_state 把登录态保存下来Playwright 最实用的一个功能就是storage_state。它能把浏览器当前上下文的 Cookie、LocalStorage 等状态序列化保存到本地文件之后创建新上下文时直接加载就相当于续上了登录态。保存状态的代码如下# 登录成功之后执行 context.storage_state(pathtelegram_state.json)下次启动脚本时加载这个状态文件from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(channelchrome, headlessFalse) context browser.new_context(storage_statetelegram_state.json) page context.new_page() page.goto(https://web.telegram.org/) # 这时候如果登录态有效会直接进入主界面就是这么简单。整个账号自动化的登录问题就被这个机制大大降低了复杂度。你不需要每次运行都走一遍登录只要定期检查登录态是否失效失效了重新跑一次扫码就行。5.3 登录态失效的常见原因和处理策略保存了登录态不代表永远有效。实际运行过程中登录态可能因为以下原因失效目标站点服务端重启了会话、同一账号在其他设备新登录导致旧会话被顶掉、长时间未活动导致服务端主动清理会话以及本地系统时间和服务器时间偏差过大导致会话校验异常。我的处理策略是每次运行脚本前先做一次轻量级的登录态探测。比如打开主页面后检查页面上是否存在登录二维码元素。如果存在说明登录态已经失效脚本就别硬继续了自动进入扫码等待流程等待人工扫码完成后继续执行。这里还要注意频繁通过自动化方式保持登录态本身就是一个需要克制的事情。正常的用户不会 7x24 小时在线。我把所有自动化任务集中在每天固定时段运行每次运行之间留出足够的时间间隔模拟正常的使用节奏。这不只是为了躲什么检测更重要的是让整个系统更稳健——你不需要依赖那些可能频繁变化的内部逻辑。5.4 把登录态探测写成一个单独的工具函数登录态探测这个逻辑最好独立成一个函数后面所有自动化脚本都复用。我把它放在项目里的login.py模块中核心逻辑很简单打开页面判断页面中是否出现登录二维码元素再进行分支处理。from playwright.sync_api import sync_playwright STATE_FILE telegram_state.json LOGIN_URL https://web.telegram.org/ def ensure_login(p, headlessFalse): browser p.chromium.launch(channelchrome, headlessheadless) context browser.new_context(storage_stateSTATE_FILE) page context.new_page() page.goto(LOGIN_URL) page.wait_for_timeout(3000) # 等待页面首屏渲染 # 用登录页特征元素判断当前是否已登录 qr_selector canvas, .qr-code, .login-form if page.locator(qr_selector).count() 0: print(登录态已失效请扫码登录...) page.wait_for_selector(canvas, statevisible, timeout120000) # 扫码完成后重新保存状态 context.storage_state(pathSTATE_FILE) print(登录态已更新) else: print(登录态有效) return browser, context, page这个函数会在每次脚本启动时被调用。第一次运行会进入扫码流程之后如果登录态有效就直接返回。组合起来整个账号自动化的入口就非常干净了。需要说明的是以上代码里的模块选择、选择器写得比较保守。Telegram Web 前端可能有具体的 class 名变化做这一步时真正要学的是用页面特征元素判断状态这个思路而不是照抄选择器。我用 Chrome 的开发者工具点开目标页面右上角的 Select an element 按钮逐个扫一遍需要的元素再用page.locator做微调这种思路在任何网页自动化上都通用。到这里需求分析和环境搭建的任务就算完成了。我自己的体会是做账号自动化真正考验耐心的从来不是写代码而是把需求边界想清楚、把环境锁稳定、把登录态这种地基问题提前解决好。这三件事做好了后续写具体业务脚本反而都是体力活。下一篇我会开始写 Telegram Web 页面元素的结构分析以及定时消息发送的具体实现。到时候见。
返回列表