Node.js自动化签到脚本开发指南:从抓包到部署的完整实践

📅 2026/8/5 1:28:15
Node.js自动化签到脚本开发指南:从抓包到部署的完整实践
1. 项目概述为什么我们需要一个自动化签到脚本最近几年各大电商平台为了提升用户粘性都推出了自己的积分、金币、京豆等签到奖励体系。每天打开APP点一下积少成多确实能兑换一些无门槛红包、优惠券或者实物。但问题也随之而来手动签到太反人性了。谁还没个忙到忘记的时候或者纯粹就是觉得每天重复这个动作很烦。于是“自动化签到”就成了一个刚需。我最初也是手动签到的忠实用户直到连续错过了一周的京东PLUS会员专属京豆感觉损失了一个亿。这才下定决心研究一下怎么让机器帮我干这个活儿。市面上确实有一些现成的工具或别人写好的脚本但要么功能不全要么因为平台规则变动而失效最要命的是把自己的账号密码或者关键的登录凭证比如Cookie交给一个来路不明的脚本安全风险极高。所以自己动手写一个或者至少能看懂、能维护一个就成了最稳妥的选择。这个项目就是基于Node.js环境打造一个专属于你自己的京东自动化签到脚本。它不仅能帮你自动完成每日的APP签到、领京豆、做任务更重要的是你能完全掌控它的运行逻辑、数据流向安全又放心。整个过程会涉及到网络抓包、请求模拟、定时任务、简单的数据持久化等前端/Node.js开发者熟悉的技能门槛并不高但实用性极强。2. 核心思路与技术选型为什么是Node.js在开始敲代码之前我们先得把整个自动化签到的逻辑理清楚并选择合适的技术栈。这就像打仗前的沙盘推演方向对了后面才能事半功倍。2.1 自动化签到的工作原理拆解自动化签到的本质是模拟一个真实用户的操作。对于京东这类有APP和网页端的平台我们通常有两种思路模拟APP请求推荐这是目前最主流、相对最稳定的方式。通过抓包工具如Fiddler,Charles,HTTP Debugger Pro等分析手机APP在签到过程中向服务器发送了哪些HTTP请求。然后我们用脚本程序去完全复现这些请求包括URL、请求头Headers、请求体Body等。服务器收到这些“以假乱真”的请求后就会像对待真实APP一样返回签到成功的结果。Web自动化测试使用像Puppeteer、Playwright或Selenium这样的浏览器自动化工具直接控制一个无头浏览器打开京东网页模拟点击、输入等操作。这种方式更贴近真人操作但缺点也很明显速度慢、资源消耗大、容易被反爬策略如滑块验证干扰稳定性较差。对于签到这种对时效性和稳定性要求高、且操作固定的场景方案一模拟请求是绝对的首选。它轻量、快速、精准。2.2 为什么选择Node.js作为实现语言从热搜词和网络讨论热度来看Node.js、Python、Shell脚本都是常见的选择。我选择Node.js主要基于以下几点考量生态丰富Node.js的npm生态里有大量优秀的HTTP请求库如axios,got,node-fetch、定时任务库如node-schedule,cron、数据处理库能极大提升开发效率。异步优势签到可能涉及多个串联或并行的请求比如先签到再领取签到奖励再完成某个浏览任务。Node.js天生的异步非阻塞I/O模型配合async/await语法能让代码逻辑清晰高效地处理这些网络I/O密集型任务。前后端开发者友好对于广大前端开发者或者对JavaScript/TypeScript更熟悉的同学来说使用Node.js几乎没有额外的语言学习成本可以更专注于业务逻辑。部署灵活写好的Node.js脚本可以非常方便地部署在各种环境你自己的电脑开个终端常驻、家用NAS如群晖Docker、云服务器如腾讯云函数SCF、阿里云FC等Serverless服务甚至一些支持Node.js的自动化平台如青龙面板。注意选择Python同样是一个非常好的选择其requests库同样强大生态也不遑多让。本教程选择Node.js更多是出于我个人技术栈和读者群体的考虑。核心思路是相通的你可以用任何你熟悉的语言来实现。2.3 核心依赖库介绍在开始编码前我们先认识一下即将用到的几个核心npm包axios: 一个基于Promise的HTTP客户端用于浏览器和Node.js。我们将用它来发送模拟签到所需的HTTP请求。它支持拦截器、自动转换JSON数据等特性非常好用。node-schedule: 一个基于Cron语法的任务调度器。我们可以用它来设置脚本在每天特定的时间比如早上8点自动运行。dotenv: 用于从.env文件加载环境变量。我们将把账号的敏感信息如Cookie放在这里避免硬编码在脚本中提高安全性。log4js或winston: 日志记录库。一个健壮的脚本必须有完善的日志方便我们查看运行状态、排查问题。这里我选用更轻量的console加强版但大型项目推荐使用专业的日志库。3. 前期准备抓包获取关键凭证Cookie这是整个项目中最关键、也最具技术含量的一步。我们的脚本要能“冒充”你就必须拿到和你APP登录状态绑定的唯一凭证——Cookie。3.1 抓包工具的选择与配置我强烈推荐使用HTTP Debugger Pro或Charles。Fiddler虽然经典但在抓取某些新版本APP的HTTPS流量时可能会遇到证书问题。这里以HTTP Debugger Pro为例因为它对Windows平台的支持非常友好设置简单。安装与代理设置安装HTTP Debugger Pro后打开软件它会自动在系统设置好代理。你需要在手机的Wi-Fi设置中手动配置代理服务器地址是你电脑的IP地址端口通常是8899以软件实际显示为准。安装CA证书为了解密HTTPS流量你需要在手机上下载并安装HTTP Debugger Pro生成的CA证书。通常在电脑软件上会有一个二维码或下载链接用手机浏览器访问即可安装。注意此操作有一定安全风险请确保在可信的网络环境下进行且仅用于学习目的。完成后建议移除证书。开始抓包确保手机和电脑在同一局域网。打开手机上的京东APP进行任意操作如浏览商品查看HTTP Debugger Pro的抓包界面应该能看到大量的请求记录。3.2 定位并提取京东的Cookie触发签到相关请求在手机上手动完成一次完整的签到流程。包括打开京东APP - 点击“领京豆”或“签到”入口 - 完成签到并点击领取可能出现的额外奖励如连续签到奖励。筛选与分析请求在抓包工具中你会看到大量请求。我们需要找到那些域名包含jd.com、360buy.com或jd.hk的请求特别是POST请求。一个典型的签到请求其URL可能类似于https://api.m.jd.com/client.action?functionIdsignBeanAct或包含sign、bean等关键词。复制Cookie找到最关键的请求通常是第一个签到请求查看它的Request Headers请求头。里面会有一个名为Cookie的字段其值是一长串复杂的字符串包含了pt_key,pt_pin,wskey等多个键值对。这个完整的字符串就是我们脚本需要的“尚方宝剑”。将它完整地复制下来。实操心得京东的Cookie中pt_key和pt_pin是最核心的登录态标识。pt_pin通常是你的京东账号名可能是邮箱或手机号的编码pt_key是一个有时效性的密钥。这个Cookie一旦泄露他人就能完全操控你的账号所以务必妥善保管绝对不能上传到GitHub等公开仓库3.3 安全地存储Cookie我们将使用.env文件来存储Cookie并将其加入.gitignore确保不会被意外提交。在项目根目录创建.env文件。在文件中写入# .env JD_COOKIE你刚刚复制的完整Cookie字符串 # 可以配置多个账号用或#分隔脚本稍作修改即可支持多账号 # JD_COOKIE_2第二个账号的Cookie创建.gitignore文件并确保包含.env。4. 脚本核心功能实现环境准备好了凭证也拿到了现在开始编写脚本的核心逻辑。我们将创建一个名为jd_sign.js的文件。4.1 项目初始化与依赖安装首先初始化一个Node.js项目并安装依赖。# 初始化项目 npm init -y # 安装核心依赖 npm install axios node-schedule dotenv4.2 构建基础请求客户端我们需要一个配置好的axios实例它携带了必要的请求头以模拟京东APP的请求。// jd_sign.js const axios require(axios); require(dotenv).config(); // 加载.env文件中的环境变量 // 从环境变量中读取Cookie如果配置了多个可以在这里分割成数组 const cookies process.env.JD_COOKIE.split(#).filter(c c.trim()); // 假设用#分隔多个Cookie if (!cookies.length) { console.error(错误请在 .env 文件中配置 JD_COOKIE 环境变量。); process.exit(1); } // 创建一个配置好的axios实例 const jdClient axios.create({ baseURL: https://api.m.jd.com/, // 京东API常用基础地址 timeout: 10000, // 10秒超时 headers: { User-Agent: jdapp;iPhone;10.2.0;;;M/5.0;hasUPPay/0;pushNoticeIsOpen/1;lang/zh_CN;hasOCPay/0;appBuild/167863;jdSupportDarkMode/0;ef/1;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1, // 模拟iPhone京东APP Accept: application/json, text/plain, */*, Content-Type: application/x-www-form-urlencoded, Accept-Language: zh-cn, Accept-Encoding: gzip, deflate, br, Connection: keep-alive, } }); // 请求拦截器为每个请求自动加上Cookie jdClient.interceptors.request.use(config { // 简单的多账号轮流处理示例实际可根据需要扩展 const currentCookie cookies[0]; // 这里先处理第一个账号 if (currentCookie) { config.headers.Cookie currentCookie; } console.log([请求] ${config.method.toUpperCase()} ${config.url}); return config; }, error { return Promise.reject(error); }); // 响应拦截器统一处理响应 jdClient.interceptors.response.use(response { console.log([响应] ${response.status} ${response.config.url}); return response.data; // 直接返回data部分方便处理 }, error { console.error([请求失败] ${error.message}, error.config?.url); return Promise.reject(error); }); module.exports { jdClient, cookies };这段代码创建了一个名为jdClient的HTTP客户端。关键在于User-Agent和Cookie请求头它们使得我们的请求在服务器看来就像是从一个真实的京东APP发出的。4.3 实现每日签到函数现在我们来实现最核心的签到函数。我们需要知道签到的具体API地址和参数。这需要通过抓包分析获得并且京东的接口可能会发生变化以下代码基于一个常见的接口示例你需要根据自己抓包的结果进行调整。// sign_task.js const { jdClient } require(./jd_sign.js); /** * 京东APP每日签到领京豆 */ async function dailySign() { const functionId signBeanAct; // 功能ID通过抓包获得 const body body${encodeURIComponent(JSON.stringify({ fp: -1, shshshfp: -1, shshshfpa: -1, referUrl: -1, userAgent: -1, jda: -1, rnVersion: 3.9 }))}appidldclientappleclientVersion10.2.0networkTypewifiosVersion15.0uuidopenudidsignstsv; try { console.log(开始执行每日签到...); const response await jdClient.post(client.action?functionId${functionId}, body); // 京东API通常返回一个包含code和data或message的JSON if (response response.code 0) { const beans response.data?.dailyAward?.beanAward?.beanCount || 0; console.log(✅ 签到成功本次获得京豆${beans}); return { success: true, beans }; } else { console.log(❌ 签到失败。响应码${response.code}, 信息${response.message || 未知错误}); // 有时失败信息在 response.data 里 console.log(详细响应:, JSON.stringify(response, null, 2)); return { success: false, message: response.message }; } } catch (error) { console.error(⚠️ 签到请求异常, error.message); return { success: false, message: error.message }; } } /** * 领取签到后的额外奖励例如连续签到奖励 * 这个接口通常需要在签到成功后根据返回的提示再去调用另一个接口 */ async function receiveExtraAward(awardId) { // 这里需要另一个抓包获得的接口和参数 console.log(尝试领取额外奖励 ${awardId}...); // 模拟实现 // const response await jdClient.post(another_api, { awardId }); // return response; return { success: true, message: 额外奖励领取功能待根据抓包实现 }; } module.exports { dailySign, receiveExtraAward };关键点解析functionId: 这是京东API区分不同功能的核心参数必须通过抓包准确获取。body参数非常复杂通常包含了设备指纹(fp)、会话信息等。抓包工具可以看到完整的x-www-form-urlencoded格式的请求体直接复制过来使用是最稳妥的。上面代码中的body只是一个示例模板你必须替换成自己抓包看到的真实数据。响应处理京东的API成功时通常code为0或0失败则为其他值。需要仔细解析返回的JSON结构才能准确提取出获得的京豆数量。4.4 实现更多自动化任务一个完整的“薅羊毛”脚本当然不止签到。我们还可以扩展其他常见任务思路都是一样的抓包 - 模拟请求。// other_tasks.js const { jdClient } require(./jd_sign.js); /** * 完成“浏览商品X秒”任务 */ async function browseTask() { console.log(开始浏览任务...); // 抓包获得的任务接口通常需要传递任务ID、浏览时长等参数 // const response await jdClient.post(client.action?functionIddoTask, {...}); // 模拟成功 await new Promise(resolve setTimeout(resolve, 2000)); // 模拟2秒浏览 console.log(✅ 浏览任务完成模拟); return { success: true }; } /** * 领取“下单返豆”等奖励需要先查询是否有可领奖励 */ async function claimOrderBean() { console.log(检查并领取订单京豆...); // 1. 先查询接口 // const queryRes await jdClient.get(client.action?functionIdqueryOrderBean); // 2. 遍历可领奖励列表逐个领取 // for (const award of queryRes.list) { ... } console.log(✅ 订单京豆领取完成模拟); return { success: true }; } module.exports { browseTask, claimOrderBean };4.5 整合任务与设置定时调度最后我们创建一个主文件把所有任务组织起来并用node-schedule设置定时任务。// index.js const schedule require(node-schedule); const { dailySign, receiveExtraAward } require(./sign_task); const { browseTask, claimOrderBean } require(./other_tasks); // 定义一个执行所有任务的函数 async function runAllTasks() { console.log(\n 任务开始执行 (${new Date().toLocaleString()}) ); // 1. 每日签到 const signResult await dailySign(); // 2. 如果签到成功尝试领取可能的连续签到奖励需根据签到返回判断 if (signResult.success signResult.data?.continuousAwardId) { await receiveExtraAward(signResult.data.continuousAwardId); } // 3. 执行其他任务可以增加延迟模拟真人操作间隔 await new Promise(resolve setTimeout(resolve, 3000)); await browseTask(); await new Promise(resolve setTimeout(resolve, 2000)); await claimOrderBean(); console.log( 所有任务执行完毕 (${new Date().toLocaleString()}) \n); } // 主函数立即执行一次并设置定时任务 (async () { console.log(京东自动化签到脚本启动...); // 启动时先执行一次 await runAllTasks(); // 设置每天上午8点30分执行Cron表达式: 秒 分 时 日 月 周几 // 这里设置为 30 8 * * *即每天8:30执行 const rule new schedule.RecurrenceRule(); rule.hour 8; rule.minute 30; rule.second 0; const job schedule.scheduleJob(rule, async function() { await runAllTasks(); }); console.log(定时任务已设置将在每天 ${rule.hour}:${rule.minute} 自动运行。); console.log(脚本持续运行中按 CtrlC 终止。); // 保持进程不退出 process.on(SIGINT, () { console.log(正在关闭定时任务...); job.cancel(); process.exit(0); }); })();现在一个基础的自动化签到脚本就完成了。运行node index.js它会立即执行一次所有任务然后等待每天的固定时间再次触发。5. 高级优化与部署方案基础功能跑通后我们可以考虑让它更强大、更稳定、更易用。5.1 支持多账号前面的代码只处理了一个Cookie。要支持多账号只需稍作修改在.env中用特定分隔符如#或存放多个Cookie。在jd_sign.js中将cookies变量读取为数组。修改runAllTasks函数遍历cookies数组为每个Cookie创建一个新的axios实例或动态修改请求拦截器中的Cookie头然后依次执行任务。// 在 runAllTasks 中 for (let i 0; i cookies.length; i) { console.log(\n 开始处理账号 ${i 1}); // 为当前账号创建临时客户端或设置Cookie const clientForThisAccount axios.create({...}); clientForThisAccount.defaults.headers.Cookie cookies[i]; // 用这个client执行 dailySign 等任务 // ... }5.2 添加日志与通知功能一个在后台默默运行的脚本我们必须知道它是否成功。除了控制台输出我们还可以日志持久化使用log4js库将日志写入文件方便日后排查。npm install log4js推送通知集成Server酱、PushPlus、Telegram Bot等工具将任务执行结果成功/失败、获得多少京豆推送到你的微信或手机。// 例如使用 axios 调用 PushPlus 的接口 async function sendNotification(title, content) { const token process.env.PUSHPLUS_TOKEN; await axios.post(http://www.pushplus.plus/send, { token, title, content, template: html }); } // 在 runAllTasks 最后调用 await sendNotification(京东签到完成, 成功签到获得京豆${totalBeans});5.3 选择部署环境让脚本24小时不间断运行你需要一个稳定的环境本地电脑不推荐电脑不能关机且网络要稳定。家用NAS/树莓派非常好的选择低功耗可长期开机。可以在Docker容器中运行Node.js环境并通过crontab或pm2来管理定时任务。# 使用 crontab 定时执行假设脚本路径为 /home/pi/jd_sign/index.js # 编辑 crontab: crontab -e # 添加一行每天8点30分执行 30 8 * * * cd /home/pi/jd_sign /usr/local/bin/node index.js /home/pi/jd_sign/logs/cron.log 21云服务器最稳定但需要一定成本。操作类似NAS。Serverless云函数强烈推荐这是目前最优雅、成本极低的方案。以**腾讯云函数SCF**为例将你的代码打包成ZIP。在SCF控制台创建函数运行环境选择Node.js。上传代码包执行方法填写index.js里的入口函数需要稍微调整导出格式以适配SCF。在“触发管理”中添加一个“定时触发”使用Cron表达式如0 30 8 * * * *表示每天8:30。在“环境配置”中填入你的JD_COOKIE等敏感信息。部署后云函数就会在指定时间自动触发运行按量计费每天运行几分钟几乎不花钱。5.4 应对平台更新与风控这是自动化脚本的长期战斗。京东的接口和风控策略可能会变。接口失效最明显的迹象是脚本突然连续失败返回“活动已结束”、“参数错误”等。此时需要重新抓包分析新的接口地址和参数格式更新脚本中的functionId和body。Cookie失效Cookie尤其是pt_key有过期时间。如果脚本返回“未登录”或“请重新登录”就需要重新抓包获取新的Cookie并更新.env文件。风控升级如果频繁请求可能会触发短暂的风控如请求需要滑块验证。应对策略包括降低频率不要在短时间内执行太多任务在任务间增加随机延迟如sleep(3000 Math.random() * 5000)。模拟更真实使用更贴近真实设备的User-Agent在请求头中补充更多抓包看到的固定参数。备用方案如果模拟请求完全失效可以考虑降级使用Puppeteer进行Web自动化虽然慢但更接近真人。6. 常见问题与排查技巧实录在实际运行和维护过程中你肯定会遇到各种各样的问题。下面是我踩过的一些坑和解决办法。6.1 脚本运行基础问题问题现象可能原因解决方案Error: Cannot find module axios依赖未安装在项目根目录执行npm installnode: command not foundNode.js未安装或未加入系统PATH访问Node.js官网下载安装并确保安装时勾选“Add to PATH”脚本执行立即退出无输出可能是语法错误或环境变量未加载1. 检查代码语法node -c your_script.js2. 确保.env文件在正确目录且变量名正确定时任务不执行Cron表达式错误服务器时间时区问题1. 使用在线Cron表达式生成器检查。2. 确保服务器系统时区为Asia/Shanghai。执行date命令查看。6.2 网络请求与签到失败问题问题现象可能原因排查步骤与解决方案请求超时 (timeout)网络不稳定服务器端响应慢1. 增加axios实例的timeout配置如30000毫秒。2. 检查运行脚本的服务器网络是否通畅。返回403 Forbidden或404Cookie失效接口地址(functionId)变更请求头不完整1.首要怀疑Cookie失效手动在APP操作一下重新抓包获取新Cookie更新。2. 检查请求的URL和functionId是否与抓包时一致。3. 对比抓包请求头和你代码中的请求头是否遗漏了Referer,Origin等关键字段。返回{code:3,message:活动已结束}签到接口已更新重新抓包这是最可能的原因。寻找新的签到入口抓取新的请求。返回{code:999,message:系统繁忙}服务器风控或临时故障1. 在请求间增加更长的、随机的延迟。2. 更换User-Agent。3. 等待一段时间后再试。能请求但返回数据为空或结构不符响应数据可能是gzip压缩或解析方式不对1. 在axios配置中设置responseType: arraybuffer然后手动解压gzip。2. 使用抓包工具查看原始响应内容确认JSON结构调整代码中的解析路径。6.3 抓包相关难题问题解决方案抓不到HTTPS请求内容为乱码确保已在手机安装并信任了抓包工具的CA证书。在手机浏览器访问chls.pro/ssl(Charles) 或抓包工具提示的地址下载证书。iOS需要在“设置-通用-关于本机-证书信任设置”中完全信任该证书。京东APP打开后无网络手机代理设置正确但APP启用了“SSL Pinning”证书绑定等反抓包机制。可以尝试1. 使用旧版本京东APP。2. 使用专门绕过证书绑定的工具如JustTrustMe模块配合VirtualXposed此方法较复杂且有风险。3.更简单的方法尝试抓取京东微信小程序或M端的请求有时限制较少。请求太多找不到签到接口在抓包工具中启用过滤只显示主机host包含api.m.jd.com或jd.com的请求。在手机上操作时动作慢一点操作一步回来看一眼抓包列表结合请求的URL中的关键词sign,bean,reward进行定位。6.4 部署与运行维护云函数运行超时默认超时时间可能只有3秒。在云函数配置中将执行超时时间调整为30秒或更长。日志查看如果部署在云函数或使用crontab务必配置好日志输出路径并定期查看日志这是发现问题的唯一途径。Cookie长期有效网络上流传的“不掉线Cookie”方法本质是获取wskey等长效令牌并通过特定接口刷新pt_key。但这涉及更复杂的逆向工程且存在安全风险。对于个人使用定期如一两周手动更新一次Cookie是更简单安全的选择。最后我必须强调自动化脚本是为了方便和省心但它不是一劳永逸的。平台在变规则在变你需要的是一个可维护、可调试的脚本框架而不是一个永远不变的“黑盒”。当它失效时你能根据这里提供的思路和排查方法快速找到问题并修复这才是真正的“薅羊毛”自由。