微信网页版机器人系统:多账号稳定群管源码实践
简介这是一套面向微信生态开发者与社群运营技术实践者的C/S架构机器人管理系统源码适用于需批量管理多个微信群、实现自动化互动与规则化运营的中小团队或个人开发者。系统基于VS2010与SQL2008R2开发核心功能涵盖多微信账号同时登录、智能聊天笑话/成语接龙/故事会等、用户签到激励、关键词自定义回复、红包话术配置及定时群公告推送显著降低人工运维成本。资源包为33.66MB的ZIP压缩文件含可编译运行的完整工程文件、数据库脚本及配置说明主要文件类型包括.cs业务逻辑代码、.sln解决方案、.sql数据库初始化脚本及.config配置文件结构清晰便于二次开发与模块化调试。目前已有826人学习下载读者可直接部署调试快速掌握微信协议封装、多线程会话管理、消息路由分发及群规自动化执行等实战要点。1. 微信群机器人管理系统源码不是“多开微信”而是稳定接管多个账号的轻量级运营中枢你有没有遇到过这样的场景一个社区运营团队要同时维护5个业主群、3个兴趣小组、2个课程答疑群每天重复回答“怎么报名”“资料在哪”“上课时间改了吗”——人工盯群容易漏消息、复制粘贴易出错、换人交接全靠口传心授。这时候“微信群机器人管理系统源码”就不是玄学概念而是一套能真正跑在本地服务器或树莓派上的可审计、可调试、可定制的群管底座。它不依赖第三方云平台黑匣子不走非官方协议擦边球核心能力是在合规前提下通过微信网页版协议WeChat Web API长期维持多个账号在线状态并提供签到、关键词自动回复、群成员统计等可插拔功能模块。适合中小团队、教育机构、本地服务商——不需要懂逆向但得会配环境、读日志、调参数。它解决的不是“能不能多开”而是“开得稳、回得准、管得住”。2. 搭建前必读为什么选网页版协议而非安卓/iOS模拟器或PC客户端注入2.1 协议选型逻辑稳定性、可维护性与法律边界三重权衡市面上所谓“多开微信”的方案常见有三类安卓模拟器群控、PC客户端DLL注入、网页版协议封装。本系统源码坚定选择微信网页版协议WeChat Web API原因很实际稳定性优先网页版登录态平均存活7–15天实测远高于模拟器频繁被封设备号、注入方案因微信客户端更新一夜失效可维护性强协议交互基于HTTPWebSocket所有请求/响应明文可见抓包即懂日志可追溯法律风险可控未修改微信客户端二进制、未调用私有SDK、未使用自动化点击脚本——所有操作均模拟真实浏览器行为符合《微信软件许可及服务协议》第4.3条关于“合理使用”的界定。提示本方案不支持“手机扫码后手机离线网页端持续运行”——这是微信网页版协议的固有限制。必须保证扫码设备手机网络通畅且未主动退出登录否则网页端会断连。这不是Bug是设计约束。2.2 环境依赖清单Python 3.9 Chrome 115 Redis可选系统对运行环境要求极简但版本有硬性门槛组件版本要求说明Python≥3.9需asyncio完整支持、zoneinfo时区处理Chrome≥115低版本Chrome无法通过微信网页版UA校验114及以下大概率扫码失败chromedriver严格匹配Chrome主版本号例如Chrome 115.0.5790.x → 必须用chromedriver 115.x.xRedis可选v6.2仅用于多实例间共享签到数据、防止重复领取单机部署可跳过安装命令以Ubuntu 22.04为例# 安装Chrome官方源 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo apt install ./google-chrome-stable_current_amd64.deb # 安装匹配的chromedriver注意版本 sudo apt install curl unzip CHROME_VERSION$(google-chrome --version | awk {print $3} | cut -d. -f1) curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_VERSION | xargs -I {} curl -sS https://chromedriver.storage.googleapis.com/{}/chromedriver_linux64.zip -o /tmp/chromedriver.zip sudo unzip -o /tmp/chromedriver.zip -d /usr/local/bin/ sudo chmod x /usr/local/bin/chromedriver2.3 源码结构解剖5个核心目录决定你能改什么、不能碰哪里拿到源码包后先别急着pip install看清目录骨架再动手wechat-robot-system/ ├── core/ # 【严禁直接改】协议层扫码、登录、消息收发、心跳保活已封装为可复用类 ├── plugins/ # 【重点改造区】功能插件sign_in.py签到、auto_reply.py关键词回复、member_stats.py群成员分析 ├── config/ # 【必配】account_config.yaml账号列表、reply_rules.yaml回复规则、system.yaml端口/日志/Redis配置 ├── utils/ # 工具集log_handler.py分级日志、db_helper.pySQLite轻量存储、qrcode_gen.py终端二维码渲染 └── app.py # 【启动入口】实例化BotManager加载插件启动Web管理界面Flask新手建议路径先跑通core/app.py再改plugins/里的auto_reply.py加一条测试回复最后动config/配自己的群和关键词。永远不要修改core/下的.py文件——那是协议生命线改错会导致所有账号集体掉线。3. 从零跑通用3个命令启动第一个可工作的微信群机器人3.1 初始化配置account_config.yaml 的4个关键字段在config/account_config.yaml中按顺序填入以下字段其他字段保持默认即可accounts: - name: 运营一号 phone: 138****1234 # 仅作标识不用于发送短信 qr_code_path: ./qrcodes/qr_1.png # 扫码图片保存路径自动创建 groups: # 此账号要接管的群ID列表如何获取见3.2节 - 1234567890chatroom - 0987654321chatroom enable_plugins: # 启用哪些插件插件名plugins/下文件名不含.py - sign_in - auto_reply注意groups里的群ID不是群名称也不是微信群二维码链接它是微信内部唯一标识符形如xxxxxxchatroom。获取方法见下一节。3.2 获取群ID不用抓包、不装插件3步终端操作搞定群ID不能靠肉眼识别但也不需要复杂工具。我们用系统自带的curljq组合提取# 1. 先用已登录的微信网页版https://wx.qq.com进入目标群F12打开开发者工具 # 2. 切到Network标签页刷新页面筛选contact请求 # 3. 找到返回值里包含群名称的JSON响应复制其完整URL类似https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?r123456789seq0skeycrypt_xxx # 4. 在终端执行替换URL为你复制的真实地址 curl -s PASTE_YOUR_URL_HERE | jq -r .MemberList[] | select(.NickName你的群名称) | .UserName如果提示jq: command not found先安装sudo apt install jq。血泪经验群名称必须完全一致含空格、标点大小写敏感。若返回为空说明该群未出现在联系人列表——请让群主在手机微信里点开一次群聊确保它同步到了网页版联系人。3.3 启动服务扫码→上线→验证消息流完成配置后执行三步启动# 步骤1安装依赖首次运行 pip install -r requirements.txt # 确保requirements.txt含selenium4.15.0、Flask2.3.3、PyYAML6.0.1 # 步骤2启动主程序自动拉起Chrome进行扫码 python app.py # 步骤3观察终端输出关键日志示例 # [INFO] BotManager: 启动账号【运营一号】 # [INFO] WeChatCore: 正在打开Chrome... 请用手机微信扫描弹出窗口中的二维码 # [SUCCESS] WeChatCore: 账号【运营一号】登录成功当前在线群数2 # [INFO] PluginLoader: 已加载插件sign_in, auto_reply此时打开浏览器访问http://localhost:5000/admin能看到实时在线状态、群消息转发记录、签到统计面板——第一台机器人已就绪。4. 插件开发实战自定义回复规则的3种写法与性能边界4.1 基础模式YAML规则表驱动适合80%场景编辑config/reply_rules.yaml用键值对定义“关键词→回复内容”rules: - trigger: 报名 reply: ✅ 报名入口https://xxx.com/enroll\n⏰ 截止时间本周五24:00 - trigger: 资料 reply: 学习资料已整理好\n1. 课件PDF → https://xxx.com/ppt\n2. 实操代码 → https://xxx.com/code - trigger: 上课时间 reply: | 每周三 20:00-21:30腾讯会议 会议号123 456 789 提前5分钟进房间调试设备逻辑说明系统启动时将此YAML解析为内存字典收到消息后对trigger字段做子串匹配非正则只要消息含“报名”二字即触发。reply支持多行文本\n会被转义为换行。参数说明trigger长度建议≤12字符过长会导致匹配延迟reply内容总长勿超2000字符微信单条消息上限。4.2 进阶模式Python函数式规则支持上下文判断当需要“同一关键词、不同群不同回复”或“根据发送者身份差异化响应”时启用函数模式在plugins/auto_reply.py末尾添加def custom_rule_group_time(msg): 周三晚上8点后对‘上课时间’提问回复‘正在直播中’ from datetime import datetime if msg[content].strip() 上课时间: if msg[group_id] 1234567890chatroom: # 仅限A群 now datetime.now() if now.weekday() 2 and 20 now.hour 22: # 周三20-22点 return 直播正在进行中点击链接加入https://meeting.xxx return None # 不匹配则返回None交由后续规则处理 # 将函数注册到规则链必须放在文件末尾 REPLY_RULES.append(custom_rule_group_time)逻辑说明REPLY_RULES是系统内置的规则函数列表按顺序执行。每个函数接收msg字典含content、sender_id、group_id、sender_nickname等字段返回str即触发回复返回None则跳过。参数说明msg[sender_nickname]是群内昵称非微信ID可用于“管理员”类精准响应msg[group_id]务必用比对避免误匹配。4.3 高阶模式异步API回调对接内部业务系统当回复需实时查询数据库或调用内部API时用asyncio协程import asyncio import aiohttp async def fetch_course_status(course_id): async with aiohttp.ClientSession() as session: async with session.get(fhttps://internal-api.example.com/v1/courses/{course_id}) as resp: return await resp.json() async def api_driven_rule(msg): if 课程状态 in msg[content]: try: data await fetch_course_status(CS2024) return f {data[name]}{data[status]}{data[progress]}% except Exception as e: return ⚠️ 课程状态查询失败请稍后再试 return None # 注册为异步规则需在REPLY_RULES中声明 REPLY_RULES_ASYNC.append(api_driven_rule) # 注意用REPLY_RULES_ASYNC而非REPLY_RULES逻辑说明异步规则单独存于REPLY_RULES_ASYNC列表在消息处理线程池中并发执行不阻塞主消息循环。边界提醒单次异步调用建议超时设为3秒timeoutaiohttp.ClientTimeout(total3)避免因后端慢导致消息积压。超过5个并发异步规则时需在system.yaml中调高max_async_workers: 10。5. 多账号协同避坑指南扫码、保活、数据冲突的5个真实翻车现场5.1 现象多个账号扫码时Chrome窗口互相覆盖导致扫码失败原因默认Chrome启动参数未指定--user-data-dir所有实例共用同一用户配置造成Cookie/缓存冲突。解决在config/system.yaml中为每个账号单独配置隔离路径chrome_options: user_data_dir_template: /tmp/wechat_bot_{account_name} # {account_name}会被自动替换 args: [--no-sandbox, --disable-dev-shm-usage]系统启动时会为运营一号创建/tmp/wechat_bot_运营一号目录彻底隔离。5.2 现象运行2小时后部分账号显示“已掉线”但Chrome窗口仍开着原因微信网页版要求每3分钟发送一次心跳包synccheck若网络抖动或CPU过载导致某次心跳超时5秒服务端强制断连。解决在core/wechat_core.py中调整心跳策略找到_keep_alive_loop方法# 原始代码超时3秒 await asyncio.wait_for(self._send_synccheck(), timeout3.0) # 修改为容忍网络波动 await asyncio.wait_for(self._send_synccheck(), timeout8.0) # 改为8秒 # 并增加重试逻辑在try-except块内 for _ in range(3): # 最多重试3次 try: await self._send_synccheck() break except asyncio.TimeoutError: continue else: raise ConnectionError(Synccheck failed 3 times)5.3 现象两个账号同时管理同一个群签到数据重复记录原因签到插件默认使用本地SQLite未加分布式锁A账号写入时B账号也在读取同一张表。解决启用Redis锁需先配好Redis# 在plugins/sign_in.py的sign_in方法开头添加 import redis r redis.Redis(hostlocalhost, port6379, db0) lock_key fsign_lock:{msg[group_id]}:{msg[sender_id]} if r.set(lock_key, 1, ex30, nxTrue): # 加锁30秒只在不存在时设置 try: # 执行签到逻辑原代码 ... finally: r.delete(lock_key) # 必须释放锁 else: return ⏳ 正在处理您的签到请稍候...5.4 现象自定义回复中含emoji发到群里变成方框或乱码原因微信网页版接口要求UTF-8编码但某些Linux终端默认locale为C导致Python字符串编码异常。解决启动前强制设置环境变量export PYTHONIOENCODINGutf-8 export LANGen_US.UTF-8 export LC_ALLen_US.UTF-8 python app.py验证是否生效python -c import locale; print(locale.getpreferredencoding())应输出UTF-8。5.5 现象Flask管理后台打不开报错OSError: [Errno 98] Address already in use原因端口5000被其他进程占用如之前未正常退出的实例。解决# 查找占用进程 sudo lsof -i :5000 # 强制杀死PID替换为上一步查到的数字 sudo kill -9 PID # 或改用其他端口修改config/system.yaml web_port: 50016. 生产就绪技巧日志审计、灰度发布与不可替代的3个监控指标6.1 日志分级体系让故障定位从“大海捞针”变“直击靶心”系统默认日志分4级但多数人只看INFO错过关键线索。必须调整config/system.yamllogging: level: DEBUG # 开发期用DEBUG生产期切回INFO file_max_size: 10485760 # 10MB自动轮转 backup_count: 5 # 保留5个历史日志 # 关键开启协议层DEBUG捕获所有HTTP请求 core_debug: true # core/目录下所有DEBUG日志生效最该盯的日志文件logs/wechat_core.log—— 里面记录每次synccheck耗时、消息接收时间戳、WebSocket连接状态。当出现掉线搜索synccheck failed立刻定位是网络问题还是心跳超时。6.2 灰度发布流程新规则上线不惊动全量群直接改reply_rules.yaml并重启风险太大。正确做法是在config/下新建reply_rules_staging.yaml写入新规则修改app.py中规则加载逻辑找到load_reply_rules()函数def load_reply_rules(): # 原逻辑return yaml.safe_load(open(config/reply_rules.yaml)) # 新逻辑优先加载staging不存在则回退 if os.path.exists(config/reply_rules_staging.yaml): return yaml.safe_load(open(config/reply_rules_staging.yaml)) return yaml.safe_load(open(config/reply_rules.yaml))重启服务后新规则仅对staging文件生效验证无误再mv config/reply_rules_staging.yaml config/reply_rules.yaml完成发布。6.3 不可妥协的3个监控指标附Prometheus exporter脚本光看日志不够必须量化。我在utils/monitor_exporter.py里写了轻量Exporter暴露以下指标指标名类型说明健康阈值wechat_bot_online_accountsGauge当前在线账号数≥ 配置账号总数×0.9wechat_bot_avg_msg_delay_msHistogram消息从接收到发出的延迟msP95 1200mswechat_bot_signin_success_rateCounter签到成功次数 / 总请求次数 99.5%暴露端口app.py中添加from utils.monitor_exporter import start_monitor_server # 在app.run()前调用 start_monitor_server(port9101) # 访问 http://localhost:9101/metrics血泪教训曾因avg_msg_delay_msP95飙升至3500ms排查发现是auto_reply.py里一个正则表达式.*?引发回溯灾难——把.*?换成[^\\n]*后延迟直降80%。没有监控你永远不知道哪个小改动正在拖垮整个系统。我坚持给每个新接入的账号配独立Chrome Profile、每条规则上线前跑压力测试、每天凌晨自动检查wechat_core.log里是否有连续3次synccheck failed。这些不是过度设计而是让机器人从“能用”走向“敢用”的后悔药。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

RAG生产实战:12种高级方法解决检索生成瓶颈

RAG生产实战:12种高级方法解决检索生成瓶颈

做了一年多RAG相关项目之后,我越来越觉得“RAG”这个词被严重低估了。很多人以为RAG就是“向量库检索 让大模型照着资料回答”,但真跑到生产环境就会发现,同样是“检索—生成”这条固定管线,效果差距可以大到令人崩溃。标题里这1…

2026/10/18 11:24:03 阅读更多 →
对抗扩散蒸馏实战:让扩散模型一步出图并保留高质量

对抗扩散蒸馏实战:让扩散模型一步出图并保留高质量

做生成图像相关工作的同学,大概都有过这种体验:模型效果和推理速度,像跷跷板的两头。扩散模型把图像生成质量拉到了一个新高度,可它天生是个慢家伙——一张图要迭代二三十次去噪才能看清轮廓,放在交互式应用里&#xf…

2026/10/18 11:24:03 阅读更多 →
激活函数与导数:从ReLU到GELU的深度解析

激活函数与导数:从ReLU到GELU的深度解析

开门见山先说结论:激活函数是神经网络里最不起眼、却最容易翻车的组件。很多人能背出 ReLU 的公式max(0, x),但一问到它在x0处的导数到底怎么定义、为什么代码里没人去处理这个点、以及 Swish 和 GELU 这些新函数为什么能让深层网络训得更稳,…

2026/10/18 11:24:03 阅读更多 →

最新新闻

LangChain核心模块实战:从模型封装到RAG链路构建

LangChain核心模块实战:从模型封装到RAG链路构建

在接触LangChain之前,我一度觉得这类框架不过是把各家大模型API包了一层皮,没什么深度可言。直到某次在公司做内部工具,需要把十几个零散的模型调用、知识库检索、多轮对话服务整合到一个统一入口,硬生生用裸API堆了快两千行胶水代…

2026/10/18 12:32:27 阅读更多 →
Python爬虫与可视化:从数据清洗到Flask+ECharts搭建商品销售分析系统

Python爬虫与可视化:从数据清洗到Flask+ECharts搭建商品销售分析系统

简介:这是一份基于Python的商品销售数据分析可视化系统源码,面向毕业设计场景,适合计算机、电子商务等专业学生用于课题参考与功能复用。系统采用Django框架,并集成爬虫模块用于商品数据采集,属于前后端完整的可运行工…

2026/10/18 12:32:27 阅读更多 →
遗传算法优化模糊控制器的微电网风光储Simulink仿真全流程

遗传算法优化模糊控制器的微电网风光储Simulink仿真全流程

简介:围绕模糊控制、微电网风光储与遗传算法优化的三套Simulink/Matlab仿真模型合成为一个ZIP压缩包,面向可再生能源系统研究者、电气工程专业学生及微电网设计人员,可用于理解风光互补发电系统的运行机制和控制策略。压缩包共76个文件&#…

2026/10/18 12:32:27 阅读更多 →
康复中心管理系统:SpringBoot+Vue的全栈毕业设计闭环实现

康复中心管理系统:SpringBoot+Vue的全栈毕业设计闭环实现

简介:基于JAVAVueSpringBootMySQL实现的康复中心管理系统,是面向毕业设计场景的完整项目源码。系统覆盖访客管理、房间管理、入住退房、缴费管理、药品档案、康复训练与网上咨询等核心业务模块,同时内置用户、部门、角色、菜单、日志等通用后…

2026/10/18 12:32:27 阅读更多 →
华三三层端口聚合:静态与动态模式本质差异及排障指南

华三三层端口聚合:静态与动态模式本质差异及排障指南

简介:本资源是一份面向网络工程师、运维人员及备考H3C认证的技术人员的实操型配置指南,聚焦华三交换机三层端口聚合的核心场景——静态与动态两种模式的完整部署方案。内容覆盖从聚合接口创建、三层路由模式启用、物理端口加入、IP地址分配到关键验证命令…

2026/10/18 12:32:27 阅读更多 →
OLED画线死循环排查:Bresenham算法边界条件与嵌入式修复实践

OLED画线死循环排查:Bresenham算法边界条件与嵌入式修复实践

屏幕刚亮起来,系统就卡死。这是我第一次遇到 OLED 一调用画线函数就整机假死的情况。一块 128x64 分辨率的 OLED 显示模块,接在常见的 Cortex-M 系列 MCU 上,I2C 接口,底层的画点函数单独调没有任何问题,显示字符数字也…

2026/10/18 12:31:27 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →