ARTICLE DETAIL

资讯详情

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

京东自动下单工具源码拆解:自动登录、补货监控与下单全链路

京东自动下单工具源码拆解:自动登录、补货监控与下单全链路 简介这是一套面向Python学习者与电商自动化爱好者的京东抢购助手完整源码包含自动登录、定时预约、补货监控、自动加购物车与自动下单等核心功能适合作为课程设计、期末大作业或毕设的参考项目也便于具备一定Python基础者研读调试。资源包共86个文件以30个py源码文件为主体辅以37个txt说明、4个md文档、3个html与3个js前端页面及少量css、图片等静态资源压缩包约1009KB目录按Core、GUI、Server、Scheduler、Config、Logger等模块划分结构清晰。项目提供Windows开箱即用软件与跨平台Web操作界面支持扫码登录、cookies保存加载、地址与商品ID查询库存价格、购物车增删与订单结算提交等操作。目前已有1075人学习下载读者可借此理解抢购流程的模块拆分与接口调用思路并在此基础上自行扩展功能。1. 京东自动下单工具源码拆解从自动登录到补货监控一套能跑通的工程化方案大促前夜盯着商品页面等补货手动刷新到手指发酸结果刚看到“有货”两个字点进去已经排队了——这是很多人想自己写一套京东自动下单工具的起点。标题里这份源码包覆盖了自动登录、指定时间预约商品、商品补货监控、自动加购物车、自动下单五个环节本质上是一条从“会话维持”到“库存感知”再到“订单提交”的完整链路。它适合有 Python 基础、想理解电商自动化下单底层逻辑的开发者也适合想把这套流程改造成自己监控脚本的运维同学。需要先说明这类工具的核心难点不在“下单”那一下而在登录态维持和库存变化感知的实时性源码里大部分工程量都花在这两处。下面按实际落地顺序把每个模块拆开讲清楚。2. 自动登录与会话维持京东 h5st 签名和 Cookie 保活怎么做自动登录是整个工具的地基。京东的登录态不是简单存个 Cookie 就能长期用它涉及扫码登录、短信验证、滑块验证以及请求签名参数 h5st 的动态生成。源码里通常把登录拆成“首次人工登录拿 Cookie”和“后续自动复用 Cookie”两段前者需要处理验证码后者靠定时刷新维持会话。2.1 首次登录扫码与滑块验证的处理边界首次登录建议用扫码方式因为账号密码登录触发滑块的概率更高。源码里一般会启动一个本地浏览器实例Playwright 或 Selenium打开京东登录页截取二维码图片保存到本地人工扫码后监听页面跳转跳转成功即把 Cookie 导出成 JSON 文件。# 用 Playwright 打开京东登录页并导出 Cookie from playwright.sync_api import sync_playwright import json, time with sync_playwright() as p: browser p.chromium.launch(headlessFalse) # 首次登录必须显示浏览器 context browser.new_context() page context.new_page() page.goto(https://passport.jd.com/new/login.aspx) # 等待人工扫码检测到跳转到首页即认为登录成功 page.wait_for_url(https://www.jd.com/**, timeout120000) cookies context.cookies() with open(jd_cookies.json, w, encodingutf-8) as f: json.dump(cookies, f, ensure_asciiFalse, indent2) browser.close()这段代码的关键参数是headlessFalse首次登录必须可见否则无法扫码。wait_for_url的超时设成 120 秒给扫码留足时间。导出的 Cookie 里包含pt_key、pt_pin等字段后续请求带上它们就能维持登录态。注意Cookie 有有效期通常几天到几周不等过期后需要重新扫码。2.2 Cookie 保活与 h5st 签名参数Cookie 保活的做法是定时访问一个轻量接口比如京东首页或订单列表页检查返回状态码。如果返回 200 且页面包含用户昵称说明登录态有效如果跳转到登录页说明 Cookie 失效需要重新扫码。h5st 是京东接口的签名参数出现在商品详情、库存查询、下单等请求里。它由时间戳、随机数、请求路径等字段经过特定算法生成算法会更新。源码里常见的处理方式是不自己实现签名算法而是用浏览器环境执行页面上的 JS 函数来生成 h5st。具体做法是在 Playwright 里打开目标页面通过page.evaluate调用页面暴露的签名函数拿到 h5st 后再拼接到请求里。# 在浏览器上下文里调用页面 JS 生成 h5st def get_h5st(page, api_path, body): # 页面加载后京东会把签名函数挂到 window 上 h5st page.evaluate( ([path, body]) { return window._jd_sign ? window._jd_sign(path, body) : null; }, [api_path, body] ) return h5st这里要注意签名函数名和挂载位置会变不能写死。稳妥做法是每次先加载页面再动态查找可用的签名函数。如果页面没有暴露就需要回退到逆向 JS 的方式但那个维护成本很高。我一般会优先用浏览器环境生成稳定性和可维护性都更好。2.3 登录态失效的排查顺序登录态失效时按这个顺序排查先看 Cookie 文件是否为空或字段缺失再看请求返回码401 或跳转登录页说明失效然后检查 h5st 是否生成成功生成失败会导致接口拒绝最后确认账号是否被风控比如频繁登录会触发短信验证。源码里通常会加一个check_login()函数每次下单前先调一次避免跑到一半才发现登录掉了。3. 商品补货监控与指定时间预约轮询策略和库存接口怎么选补货监控的核心是“在库存变化的第一时间知道”。京东商品页有“有货/无货”状态但页面刷新有延迟直接轮询页面效率低。更可靠的做法是调用库存查询接口传入商品 ID 和地区编码返回库存数量。源码里一般用轮询方式间隔从 1 秒到 10 秒不等具体看商品热度。3.1 库存查询接口的参数与地区编码库存接口通常需要skuId、area、num三个参数。skuId是商品编号从商品链接里提取area是地区编码格式如1_72_2799_0代表省_市_区_镇num是购买数量。地区编码可以通过京东的地址接口获取也可以从已登录账号的默认地址里读。# 查询商品库存 import requests def check_stock(sku_id, area, cookies): url https://c0.3.cn/stock params { skuId: sku_id, area: area, num: 1, callback: jQuery123456 } headers {User-Agent: Mozilla/5.0, Referer: fhttps://item.jd.com/{sku_id}.html} resp requests.get(url, paramsparams, cookiescookies, headersheaders, timeout5) # 返回是 JSONP需要去掉回调函数名再解析 text resp.text json_str text[text.index(()1 : text.rindex())] data json.loads(json_str) return data.get(stock, {}).get(StockState, 0) # 33 表示有货StockState为 33 时表示有货34 表示无货36 表示采购中。轮询间隔建议设 2 到 5 秒太短容易触发风控太长会错过库存。源码里通常会把轮询和下单放在两个线程里监控线程发现库存后立即通知下单线程。3.2 指定时间预约商品的定时触发“指定时间预约”指的是在某个时间点比如 10:00:00准时发起下单请求。实现方式有两种一种是用schedule库在本地定时另一种是提前把请求准备好到点直接发送。源码里常见的是第二种因为网络延迟不可控提前 100 到 200 毫秒发送反而更容易抢到。# 定时触发下单 import time, threading def schedule_order(target_time, order_func): while True: now time.time() if now target_time - 0.15: # 提前 150ms 触发 order_func() break time.sleep(0.01) # 10ms 精度轮询这里的关键是time.sleep(0.01)用 10 毫秒精度轮询避免睡过头。提前 150 毫秒是经验值具体看网络 RTT。如果服务器时间有偏差可以先用一个请求测出时间差再校准本地触发时间。3.3 补货监控的轮询频率与风控边界轮询频率不是越高越好。实测 1 秒一次连续跑 10 分钟大概率会触发京东的访问频率限制表现为返回 403 或要求验证。稳妥做法是日常监控用 5 秒间隔大促前 10 分钟切换到 2 秒同时给请求加随机延迟比如 0.5 到 1.5 秒之间随机。源码里如果没做这个随机化跑一段时间就会被限流。4. 自动加购物车与下单请求构造和参数校验的完整链路加购物车和下单是两个独立接口但通常连着调用。加购物车接口需要skuId、num、area等参数下单接口还需要收货地址 ID、支付方式、发票信息等。源码里一般把这两步封装成一个buy()函数内部先加购再下单任一步失败就重试。4.1 加购物车接口的请求体构造加购物车接口是 POST 请求请求体是 JSON 格式。关键字段包括skuId、num、area、canBuyNum。其中canBuyNum是限购数量从库存接口返回的数据里取。# 加入购物车 def add_to_cart(sku_id, num, area, cookies): url https://cart.jd.com/gate.action data { pid: sku_id, pcount: num, ptype: 1, area: area } headers { User-Agent: Mozilla/5.0, Referer: fhttps://item.jd.com/{sku_id}.html, Content-Type: application/x-www-form-urlencoded } resp requests.post(url, datadata, cookiescookies, headersheaders, timeout5) return 成功 in resp.text or resp.status_code 200ptype1表示普通商品。返回内容里如果包含“成功”或状态码 200说明加购成功。注意加购接口也会校验登录态和 h5st如果返回“请先登录”说明 Cookie 失效。4.2 下单接口的收货地址与支付参数下单接口需要更多参数addressId收货地址 ID、payType支付方式如 4 表示在线支付、invoiceInfo发票信息、token防重放令牌。addressId可以从账号的地址列表接口获取token通常在下单页面里。# 提交订单 def submit_order(sku_id, num, address_id, cookies): url https://trade.jd.com/shopping/order/submitOrder.action data { overseaPurchaseCookies: , vendorRemarks: [], submitOrderParam.skuIds: f{sku_id},{num}, submitOrderParam.addressId: address_id, submitOrderParam.payType4: 1, submitOrderParam.btSupport: 0, submitOrderParam.trackId: test_track } headers { User-Agent: Mozilla/5.0, Referer: https://trade.jd.com/shopping/order/getOrderInfo.action } resp requests.post(url, datadata, cookiescookies, headersheaders, timeout5) return resp.json()返回 JSON 里success为 true 表示下单成功orderId是订单号。如果返回“库存不足”说明下单瞬间库存被抢完需要重新监控。如果返回“请勿重复提交”说明 token 失效或请求重复。4.3 下单失败的重试与幂等处理下单失败分两类可重试的网络超时、库存瞬时不足和不可重试的地址无效、账号被限制。源码里一般对可重试错误做 3 次重试间隔 200 毫秒。但要注意幂等同一商品重复下单会生成多个订单所以重试前要先查一次订单列表确认没有已生成的订单。# 带幂等检查的重试 def safe_order(sku_id, num, address_id, cookies, max_retry3): for i in range(max_retry): result submit_order(sku_id, num, address_id, cookies) if result.get(success): return result if 重复 in result.get(message, ): return result # 已下单不再重试 time.sleep(0.2) return {success: False, message: 重试耗尽}5. 避坑与排查自动下单工具最容易翻车的 5 个地方这套工具跑起来不难难的是稳定跑。下面 5 个坑是我在实际调试里反复遇到的每个都按“现象 → 原因 → 解决”写清楚。坑一Cookie 突然失效所有请求跳登录页。现象是监控还在跑但加购和下单全部返回“请先登录”。原因是京东对 Cookie 有有效期且异地登录或频繁请求会提前失效。解决方法是加一个定时检查每 30 分钟调一次用户信息接口失效就重新扫码并把新 Cookie 写回文件。坑二h5st 生成失败接口返回 403。现象是请求头里带了 h5st但接口仍然拒绝。原因是签名函数名变了或者页面没加载完就调用了。解决方法是先page.wait_for_load_state(networkidle)再取签名并且每次请求前重新生成不要缓存。坑三轮询太频繁被限流返回 403 或验证码。现象是监控跑了几分钟后库存接口开始返回 403。原因是请求频率超过风控阈值。解决方法是在轮询里加随机延迟间隔从 2 秒到 5 秒随机并且每 100 次请求后暂停 10 秒。坑四下单成功但没付款订单超时取消。现象是submitOrder返回成功但订单列表里显示“待付款”一段时间后自动取消。原因是下单接口只创建订单不完成支付。解决方法是在下单成功后立即调用支付接口或跳转收银台至少要在超时前完成支付。坑五多线程同时下单生成重复订单。现象是监控线程发现库存后多个下单线程同时提交生成两笔订单。原因是没有加锁。解决方法是用threading.Lock()包住下单逻辑确保同一商品同一时间只有一个线程在提交。6. 进阶技巧用青龙面板做定时任务与多账号隔离如果想让这套工具长期跑不建议在本地开个终端挂着。更稳的做法是放到青龙面板里用它的定时任务和环境变量管理多账号。青龙面板支持 Python 脚本可以把 Cookie 存成环境变量每个账号一个变量名脚本启动时读取。具体做法把源码里的 Cookie 文件读取改成从环境变量读变量名格式如JD_COOKIE_1、JD_COOKIE_2。然后在青龙面板里创建定时任务比如0 9 * * *表示每天 9 点执行一次补货监控。多账号之间用不同的area和addressId避免下单时地址冲突。# 从环境变量读取多账号 Cookie import os def load_cookies(): cookies_list [] for key, value in os.environ.items(): if key.startswith(JD_COOKIE_): cookies_list.append(value) return cookies_list青龙面板的好处是任务隔离和日志集中哪个账号失效了一眼能看到。但要注意面板本身不解决 h5st 和风控问题它只是调度器。签名和登录态还是得靠浏览器环境或逆向方案。最后说个我自己的习惯每次改完脚本先拿一个不重要的商品跑一遍全流程确认登录、监控、加购、下单都通了再切到目标商品。这样翻车成本最低。希望帮到你。本文还有配套的精品资源点击获取
返回列表