十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

基于Python的微信小程序讲座抢报名脚本设计与实现

基于Python的微信小程序讲座抢报名脚本设计与实现 简介本资源是一套面向Python初学者与自动化工具开发者的微信小程序讲座抢报名实战脚本旨在解决热门讲座名额秒光、人工操作响应滞后等实际痛点适用于高校学生、技术爱好者及需高频参与线上讲座报名的用户。压缩包共35个文件大小1.41MB包含3个核心Python脚本实现登录、信息识别、自动提交逻辑、5个XML配置文件用于界面元素定位与参数映射、18个PNG及2个JPG图像资源含登录页、讲座页、图标等UI截图支撑OCR或模板匹配、2个ICO图标及配套README和requirements.txt等工程辅助文件结构完整、开箱即用。已有859人学习下载提供从环境配置到关键函数注释的完整实现路径涵盖GUI界面调用、小程序页面解析、并发请求控制等典型自动化场景虽已停止更新但代码逻辑清晰、模块解耦合理是理解小程序前端交互与Python自动化协同的优质参考案例。 讲座名额一分钟内被抢光这个场景估计很多学生党都经历过。去年学院办学术讲座120个名额三秒就没了我点进去的时候只剩下“已报满”。后来我写了一个基于Python的微信小程序讲座抢报名脚本把报名流程拆成定时触发和自动提交最终在名额开放后一秒内完成报名。这个项目不只为了一次抢名额更是一次很好的接口调试、自动化脚本设计练习适合正在学Python、想接触微信小程序数据交互、对HTTP接口调试感兴趣的开发者参考。本文会把整套设计思路、抓包方法、核心源码结构和踩坑记录都写出来你可以拿它当模板改成其他类似场景的自动化工具。1. 项目要解决的真实问题与最终落地的形态1.1 讲座报名的痛点名额有限、手速不稳、时间卡不准微信小程序里的讲座报名和网页端的秒杀逻辑很像活动方提前发布报名入口到某个整点开放名额先到先得。问题在于你不可能一直盯着手机屏幕更不能保证自己点击提交的瞬间网络是稳定的。我遇到的典型场景是名额开放前半小时我还在实验室调代码等到想起来时报名已经截止。另一类场景更折磨人——你明明守着手机到点就点结果名额开放那一下小程序页面还在加载封面图等进入报名页已经显示“名额已满”。这个项目的核心价值就是把“人工盯守”换成“程序定时触发”。准确说它做的事情很简单提前登录小程序拿到有效凭证确认活动ID和报名参数在设定的开放时间点到来时由脚本自动向报名接口发起一次提交请求。整个过程不涉及点击手机屏幕也没有模拟器刷机本质上是一个更快的客户端。它只解决“手速不够快”“反应不够及时”这两个问题并不改变报名规则本身。1.2 最终落地形态一个命令行工具加一份配置文件项目跑通之后最终形态是这样一个东西一个Python命令行工具放一份JSON配置文件里面记录活动ID、报名开始时间、登录凭证、接口地址等关键信息。运行python main.py --config config.json之后脚本会启动一个内置的定时任务到了约定时间自动执行报名流程。执行结果会写入日志文件成功或失败都看得到。我没有把它做成一键双击安装的程序原因很简单——它本来就是我自己的辅助工具不是面向大众的产品。命令行的好处是启动逻辑清晰、方便部署到服务器或旧电脑上跑也方便接Linux的cron定时任务。如果你想做得再友好一点可以在这个基础上加一个简单的Web界面或者用企业微信机器人推送报名结果这些后面我会讲到。结构上它保持了足够克制每个模块都能单独调试这也是整个项目没有失控的关键。1.3 技术选型为什么是Python加requests而不是别的方式选型时我考虑过三条路线。第一条是用Selenium或Playwright这类浏览器自动化工具但它们面对的是网页微信小程序不是网页底层是原生组件加WebView混排模拟器里打开小程序的成本很高而且还容易触发登录风控。第二条是直接在微信开发者工具里写自动化测试脚本这确实能绕过很多问题但开发者工具更多面向小程序开发方我作为普通用户拿不到原始工程和AppID这条路走不通。第三条就是最终采用的方案抓包分析小程序报名接口直接用Python的requests库模拟请求。requests方案的最大优势是轻量。一顿操作后你只需要维护一个HTTP请求不依赖浏览器环境运行效率也高。再加上Python有APScheduler、loguru这类现成库定时任务和日志记录都省了很多事。如果你对HTTP协议有一定了解这个方案的调试成本其实非常低。当然它也有明显的技术门槛你必须能从小程序里拿到登录态并且正确还原请求头。这两点搞定了整个项目基本就完成了一半。2. 小程序报名链路的抓包拆解从点按到提交的数据流2.1 抓包前的准备拿到小程序发出去的每个请求想还原报名接口第一步是抓包。我用的工具是Charles同类工具还有Fiddler、mitmproxy选哪个按操作系统来关键流程是一致的。安装完成后需要做两步准备第一步是开启HTTPS解密让Charles能读取加密传输的内容第二步是让手机信任Charles的SSL证书同时把手机WiFi代理指向运行Charles的电脑。做过一次之后你会明白这其实就是搭建一个本地HTTPS中间人监听环境所有经过手机的流量都会先到你电脑上转一圈。需要注意如果小程序做了证书固定比如只在代码里信任特定证书抓包工具会解不开HTTPS流量。我在另一些App上遇到过这种情况微信小程序一般比较少这样做但保不齐。遇到证书校验时不要想着硬绕过那既麻烦又容易踩红线更稳妥的办法是改用Android模拟器里的小程序、或者联系活动方要测试环境。就本项目的场景来说绝大多数校园活动小程序不会做太强的证书校验正常抓包足够用。2.2 定位报名接口别把时间浪费在无关请求上打开待报名的讲座小程序随便点几个页面Charles里会刷出一堆请求。这时候别慌按下面几步过滤就能很快定位目标接口。先按域名过滤一般小程序的所有业务请求都会指向同一个后端域名比如api.lecture.edu.cn。然后在过滤后的请求列表里手动在小程序里走一遍报名流程打开活动详情、点击报名按钮、看到“报名成功”的提示。操作期间记录下所有新增的请求重点看POST方法、路径带apply、sign、register、enroll这类关键词的接口。我这次遇到的核心接口路径是/api/activity/apply参数包括activityId、timestamp、sign返回的JSON里有一个code字段为0表示成功。从浏览器角度理解这个接口就相当于表单的提交地址activityId是你要报名的活动编号timestamp是当前时间戳sign是防篡改签名。搞清楚这三个参数脚本的核心逻辑就浮出水面了。参数名含义获取方式activityId活动编号活动详情页请求的返回timestamp客户端时间戳脚本运行当前时间userId / token用户身份标识登录后由后端下发sign请求签名由部分参数加固定密钥哈希生成2.3 登录态的携带方式header里的token还是cookie小程序登录和浏览器登录不太一样。浏览器里你用账号密码登录后后端通常下发一个Cookie之后每次请求自动带上。小程序没有传统意义上的Cookie机制大多数是调wx.login()拿到临时code再把code交给后端换取一个自定义的token或openid关联信息。拿到token之后后续请求一般放在请求头里常见的字段名是Authorization: Bearer xxxxx或X-Token: xxxxx。在实际抓包里你不需要理解完整的小程序登录协议只需要找到“用户身份凭证”长什么样然后在脚本里原样带上即可。我在Charles里选中报名请求在Headers面板看到X-Token: a1b2c3...把它复现到requests请求头里就搞定了。要注意token通常有时效短则半小时长则几天。如果你的小程序token很容易过期脚本里最好加入自动刷新逻辑——通过另一个登录接口重新获取token。如果活动方允许长期登录保持那更省事直接配置token就能用。2.4 一次成功报名背后的完整请求序列很多人以为直接调报名接口就够了实际上很多小程序对请求流程有前置依赖你得先拿到活动的activityId可能还要先查一下活动状态是“报名中”才行。我在第一次跑脚本时就翻过车直接向/api/activity/apply发POST结果返回“活动不存在”。后来抓包发现小程序在进入活动详情页时先请求/api/activity/detail拿到了活动状态、剩余名额、活动ID等信息然后才允许报名。所以我的脚本里保留了这样的请求序列第一步请求活动详情解析返回的JSON检查status字段是否为“可报名”第二步如果可报名往报名接口提交activityId和timestamp第三步解析报名结果根据code字段判断是否成功。这样三步走下来基本能复刻小程序内的完整行为。当然有更激进的优化方案——跳过详情页直接构造报名请求可以省几十毫秒但会牺牲对活动状态的判断。我的选择是保留详情页请求因为它能在每轮预检查中告诉你“活动还没开放”或“已经满员”这对定时任务而言是很有用的状态信号。3. 环境准备与依赖安装Windows、macOS、Linux都能跑3.1 Python环境与虚拟环境踩过最深的一次坑整个项目对Python版本的要求不高3.9及以上完全够用。但我要特别强调虚拟环境这件事。很多人拿到源码第一件事就是在全局环境里pip install -r requirements.txt等到下一次做别的项目时发现依赖冲突。我的建议是最开始就建一个隔离环境命令很简单python -m venv venvWindows下激活虚拟环境是venv\Scripts\activatemacOS和Linux是source venv/bin/activate。激活后你会看到命令提示符前面出现(venv)前缀这时候再安装依赖所有包都会装进项目目录不会污染系统环境。这个习惯早期没养成后来排查一个pandas版本冲突问题花了整整半天从那以后我所有Python项目第一件事就是建虚拟环境。3.2 依赖库requests、APScheduler、loguru、ntplib这个项目基础依赖真的不多就四个库。requests负责HTTP请求没什么可说的APScheduler负责定时触发比手动time.sleep()循环可靠得多loguru负责日志输出比标准logging库的配置简洁ntplib用来做网络时间同步避免本机时间不准导致提前或延迟提交。requirements.txt长这样requests2.31.0 APScheduler3.10.4 loguru0.7.2 ntplib0.4.0为什么不用时间定时任务替代APScheduler因为APScheduler能处理“错过触发时间”的补偿逻辑。比如脚本在报名开放前2分钟因为网络中断重启了重启后APScheduler会检测到任务周期已过并立即补一次执行而time.sleep方案遇到这种情况就直接错过。对你的抢报名场景来说错过一次可能就没了。另外APScheduler还支持抢占式调度可以设定任务开始前10秒每500毫秒检查一次活动状态很方便。3.3 Windows用户最常见的“命令无法识别”问题这个坑我是在帮同学迁移项目时遇见的。他在Windows PowerShell里输入python main.py系统直接报“无法将‘python’项识别为 cmdlet、函数、脚本文件或可运行程序的名称”这和网上很多人遇到的npm、opencode无法识别是同一个原因——Python没有加到系统环境变量PATH里终端在当前目录下找不到这个命令。解决方法是找到Python安装路径比如C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\把它的Scripts子目录一起加到PATH里。检查是否配置成功重新打开终端输入python --version即可。如果你安装Python时忘了勾选“Add Python to PATH”最简单的补救是卸载重装安装向导的叉不能漏。这个问题虽然不是项目本身的逻辑错误但对新手来说非常劝退所以我特意放在环境准备这一节。3.4 Linux服务器部署cron还是shell包装脚本如果你有闲置的Linux服务器或云主机把脚本部署上去是最稳的。电脑可以关服务器常年在线。我自己试过用crontab跑但直接用cron调用带虚拟环境的Python脚本有个小坑——cron的环境变量很干净经常找不到python命令和依赖包路径。更稳的做法是写一个shell包装脚本在里面先激活虚拟环境再执行主脚本#!/bin/bash cd /home/user/lecture_sign source venv/bin/activate python main.py --config config.json logs/cron.log 21把这段保存为run.sh并赋予执行权限chmod x run.sh然后在crontab里添加一行定时任务。注意cron用的是标准时间如果你的服务器时区不对报名开始时间会差好几个小时部署后一定要用date命令确认时区必要时把系统时区改成Asia/Shanghai。这些细节不处理很容易在关键时间点翻车。4. 核心模块设计与源码结构一份可落地的工程骨架4.1 顶层目录结构与文件职责这个项目我最终整理成六个文件不算多但每个职责都清楚。main.py是入口负责解析参数、初始化配置、启动调度器config.json存放所有可调参数不写死代码里scheduler.py封装APScheduler的定时任务逻辑login.py处理登录态包括从配置读取token和刷新tokensigner.py实现核心报名逻辑也就是向报名接口发送请求utils.py放一些公共函数比如日志初始化、时间同步、请求头构造。目录结构如下lecture_sign/ ├── main.py ├── config.json ├── requirements.txt ├── scheduler.py ├── login.py ├── signer.py ├── utils.py └── logs/没有必要加更多抽象层比如views、models、controllers那套对一个几十行核心逻辑的脚本来说纯属过度设计。我见过很多人写自动化脚本也硬套Django项目结构最后代码量翻倍维护起来还更费劲。能用函数解决的就不用类能用模块解决的就不建包这是我对小型自动化工具体系的一贯原则。4.2 配置管理把报名参数和接口地址抽出来所有环境相关的参数都应该放进配置文件而不是写在代码里。我这里的做法是维护一个config.json里面记录活动ID、报名开始时间、接口域名、token、请求超时时间、重试次数等。这样换一个活动时只需改配置文件不用动任何代码。示例配置如下{ activity_id: 20240908, start_time: 2024-09-08 10:00:00, domain: https://api.lecture.edu.cn, apply_path: /api/activity/apply, detail_path: /api/activity/detail, token: a1b2c3..., timeout: 5, max_retry: 3 }有人可能会问活动ID和报名开放时间这种敏感信息放配置文件里安全吗我的理解是这个脚本本来就是在你自己的电脑或服务器上运行不对外发布配置文件里是你的个人token没有泄露风险。如果以后要做成多人使用的小工具那token应该改成登录输入或者从环境变量读取而不是直接放明文JSON。我在代码里用的是config.json直接读取因为项目规模小还没有到需要加密处理的级别。4.3 登录态管理与自动刷新登录态是整个脚本正常工作的前提。我在login.py里做了一个简单的token管理器每次请求前检查token是否过期如果过期就调用小程序后端的刷新token接口。刷新token接口通常需要refresh_token参数可能还有签名校验具体字段要从抓包里抠出来。如果服务端不支持自动刷新那就只能重新去小程序里登录一次把新的token抄到配置文件里。def get_valid_token(): token load_token_from_config() if is_token_expired(token): token refresh_token() save_token_to_config(token) return tokenis_token_expired实现方式一般有两种一是看token里的过期时间戳JWT格式的token可以直接decode出来二是调用一个轻量接口比如“获取用户信息”来试探如果返回401就说明失效。我比较推荐第一种不用额外请求解析起来也快。但注意不是所有token都是JWT有些是普通随机字符串可能没有过期时间字段这时候就只能靠第二种方式回调验证。好在大多数高校活动小程序的token有效期至少有半天报名过程十几分钟就结束过期问题不太容易出现。4.4 报名核心模块时间同步、预检、提交这是整个项目最核心的部分。报名流程我拆成三个步骤。第一步是时间同步用ntplib从NTP服务器拉取精确的当前时间避免本机时间快慢导致提前提交被拒或延迟提交被占完名额。第二步是预检请求活动详情接口判断活动状态。第三步是提交如果状态允许报名就立即发送报名请求。核心代码片段是这样的import requests import ntplib import time def get_server_time(): client ntplib.NTPClient() response client.request(ntp.aliyun.com, timeout2) return response.tx_time def apply_activity(config, token): headers { Content-Type: application/json, X-Token: token, User-Agent: Mozilla/5.0 (Linux; Android 12) AppleWebKit } payload { activityId: config[activity_id], timestamp: int(time.time()), sign: generate_sign(config[activity_id]) } resp requests.post( config[domain] config[apply_path], jsonpayload, headersheaders, timeoutconfig[timeout] ) return resp.json()时间同步这个函数在报名开始前10秒会调用一次拿到服务器标准时间然后脚本根据这个时间校准自己需要等待的秒数。这里有个关键细节不要用NTP服务器时间和本机时间的差值来修改本机时间只把它用来计算“距离开始时间还剩多少毫秒”。这样处理的好处是即使本机时间偏差很大脚本也能以服务器时间为基准精确触发同时不影响电脑上的其他应用。generate_sign函数我在这里省略了细节因为你抓包时不一定能看到完整签名算法可能是简单的MD5哈希也可能涉及固定盐值这个只能在真实接口上逆向后决定。4.5 结果处理日志、成功状态和提醒提交报名之后不能只看一眼屏幕就过去我把结果处理也做成了独立模块。一个简单的逻辑是请求返回的JSON里如果有code 0代表报名成功日志记录“报名成功订单号xxx”如果返回code 1可能是“活动未开始”或“名额已满”这时候根据具体提示决定是否继续重试。loguru库在这个阶段的优势就体现出来了它能把不同级别的日志用不同颜色输出到终端同时写入文件方便事后复盘。如果你希望报名成功后第一时间收到通知可以用企业微信机器人、钉钉机器人或者Server酱推送一条消息到手机。推送逻辑不复杂本质就是再调用一个Webhook地址把成功信息发过去。我最初选的是Server酱注册后得到一个key构造一条URL请求即可。这样人在操场、在食堂收到推送就知道报名成功了不用一直盯屏幕。5. 实测踩坑记录那些不跑一遍根本发现不了的问题5.1 请求头缺一个字段等于直接拒绝第一次跑脚本时我把请求体重现得一模一样却一直收到401。反复比对抓包数据才发现小程序请求头里有一个叫X-Requested-With的字段值是com.tencent.mm。这是微信WebView环境里特有的标记后端拿它判断请求是否来自微信客户端。requests默认不会带这个头服务端校验不通过就直接拒绝。这个坑给了我很深的教训任何请求头字段哪怕看起来没意义也要先原样搬进脚本再说。你永远不知道后端到底依赖哪个字段来做安全校验可能是Referer可能是Origin也可能是某个自定义的X-开头字段。应对方法很笨但有效——把Charles里看到的请求头Headers面板整个截下来跟requests库发出去的请求头逐一对照。排查疑点时要特别注意那几个“多余”的字段它们往往才是后端的真实校验点。5.2 报名接口的时间基准是服务器时间不是本机时间有一次我本机时间快了45秒脚本在本机时间10点00分01秒触发但服务器实际还没到开放时间接口返回“活动未开始”。反过来如果本机时间慢了脚本就会比别人慢半拍名额大概率已经被抢完。这个问题单靠设置系统时间自动同步不够因为Windows和macOS的网络时间同步精度有限而且很多电脑休眠唤醒后时间会有几秒偏差。解决方案我在4.4里提过了用ntplib去拉标准时间。这里补充一个实操经验NTP请求不要放在报名前最后一秒因为网络波动可能导致请求延迟反而拖累了触发时机。我把时间同步放在报名开始前10秒然后把这个标准时间缓存起来之后脚本内部的倒计时循环一律用这次同步结果作为基准。这样即使后面网络拥塞NTP请求也不会影响关键路径。5.3 连续高频失败触发风控退避策略不能少脚本在调试阶段最容易犯的错就是失败后立刻重试而且不限制次数。我有一天晚上测试接口连续发了几十次请求结果IP被服务端临时封锁之后所有请求都返回“访问频繁”。这个封锁持续了大概半小时正好错过了当时的测试活动。从那以后我在代码里加了严格的重试控制每次报名任务最多重试3次如果失败就停止不进行无限重连。退避策略也很有讲究。第一次失败后等2秒再试第二次失败后等4秒第三次失败后直接放弃并记录日志。这叫指数退避是用来给服务端留出恢复时间的通用做法。真正到了报名开放时刻你的脚本只会在允许的时间窗口内发起极少量请求而不是像压测工具一样疯狂打接口。慢就是快这句话在服务端限流面前非常真实。5.4 多线程在这里反而帮倒忙写完第一版脚本后我一度很纠结要不要用多线程并发提交多个报名请求想着这样成功率更高。后来测试发现完全不是这样。首先同一个用户账号多次提交同一个活动服务端大概率做了幂等处理——第一个请求成功后后续请求都会返回“请勿重复报名”。其次多线程并发会打乱请求顺序当多个请求同时到达时服务端的签名校验和时间戳校验可能出现微妙失败。更关键的是多线程如果触发了风控原本一次成功就能解决的事反而会变成IP被禁、一个也报不上。我最终的选择是单线程加一次提交在提交之前用预检接口确认活动状态这样整个报名过程只有一次有效POST请求。从工程角度讲自动化脚本的第一目标“不出错”远重于“速度快”。5.5 网络环境差异校园网、4G、家庭宽带的坑同样一段脚本换一个网络环境可能表现完全不同。校园网通常走运营商NAT出口IP是共享的如果很多人同时报名服务端看到同一个IP段的大量请求可能误判为攻击。4G网络延迟不稳定有时提交请求发出去了但响应超时脚本可能误判失败。家庭宽带相对稳定但如果之前开过抓包工具的本地代理脚本里又忘了关闭代理配置requests可能一直把请求转发到一个不存在的端口导致连接失败。实操上有两个细节要养成习惯。第一个是requests.post时显式传入一个proxies参数或设置环境变量NO_PROXY确保脚本不读取系统代理。第二个是在脚本启动时自动探测网络连通性用一个简单的GET请求到目标域名测一次往返延迟如果延迟超过500毫秒就在日志里警告这样你能提前判断当天的网络状态适不适合准点报名。这些小细节不处理真到关键时候任何一环都可能掉链子。6. 合规边界与后续扩展脚本能做但要知道红线在哪里6.1 自动化脚本的正当用途个人辅助、测试调试、接口学习写这个脚本并不等于鼓励所有人去抢热门名额。它真正的正当用途有三类。第一类是个人报名辅助比如你已经通过内部渠道拿到了活动资格只是需要到点填一下报名表单脚本代替你完成这个动作不涉及跟别人争抢公共资源。第二类是测试调试你正在开发自己的小程序或Web应用需要模拟高并发报名场景来压测服务端接口这类脚本是标配工具。第三类是接口学习通过抓包和模拟请求你能直观理解HTTP请求、token认证、签名机制这些知识这是任何书本都比不了的实战经验。我自己后续也把这段逻辑复用到了另一个项目里做一个自动填写问卷的程序每小时检查一次服务端配置发现新发布的问卷就自动提交。这类工具只要遵守被访问服务的规则用途完全是正当的。脚本本身没有善恶关键看你怎么用。6.2 不越过的红线验证码、多账号、服务端攻击写自动化脚本有一个基本底线不要试图打破平台设计的公平规则。具体到本项目来说明确不做的有三件事。第一是不绕过验证码如果服务端在报名时弹出滑块验证码说明平台已经在用技术手段限制自动化那就应该理解为规则不允许脚本报名停止使用而不是研究怎么破解。第二是不用多账号批量刷名额这会直接剥夺其他真实用户的机会一旦被识别出同一设备同一IP短时间内大量报名账号可能被冻结。第三是不对服务端发起超出正常范围的请求压力比如用分布式IP轰炸报名接口这已经属于破坏计算机信息系统的范畴。我在项目README里写了一句很直白的话这个脚本不会让你在所有抢座大战中所向披靡它只是在规则允许的范围内替你按下了报名按钮。如果你想要的是“无论多少人都能抢到”的效果那这个脚本帮不了你也不应该帮。6.3 从抢报名脚本到通用表单自动填写工具最后聊聊扩展方向。这个项目跑通之后我很快意识到报名接口和普通表单提交没有本质区别于是把配置从“活动报名”改成了“通用表单提交”。新的config.json里增加了form_fields数组每个字段对应表单里的一个表单项比如姓名、学号、手机号。这样脚本就不只服务于讲座抢报名遇到需要定时抢的实验课、体育课、志愿活动只要改一下配置就能复用。更进一步你还能把它扩展成企业微信机器人助手。把报名结果发送到群里让同事或同学都看得到。或者写一个简单的FastAPI服务把配置管理做成网页页面手机浏览器就能改活动时间、改报名参数。这个方向看着复杂底层逻辑还是那几件事定时触发、登录态、接口请求、结果通知。把这一套吃透了你以后再面对任何“到点提交”的自动化需求都能很快做出一个能用的小工具。最后说一点我个人的感受。写这个脚本之后我其实几乎没用它去抢过什么热门讲座因为一次成功后我发现真正的收获反而是把报名链路彻底搞清楚了。如果你也想做类似的东西我建议先在自己有权限管理的小程序或测试环境里练手跑通之后再考虑真实场景。源码能帮你节省大量踩坑时间但不管代码跑得多快先想清楚边界在哪里。工具永远是工具使用它的那个人才是决定事情性质的关键。本文还有配套的精品资源点击获取
返回列表