教你用Python写一个京东自动下单抢购脚本(Python实现京东自动抢购)

2023-05-16

很多朋友都有网购抢购限量商品的经历,有时候蹲点抢怎么也抢不到,今天小编带你们学习怎么用Python写一个京东自动下单抢购脚本,以后再也不用拼手速拼网速啦,快来一起看看吧

1 问题背景

经过无数次抢购失败后,发现商家会不定时的放出少量货源,目测每次会有几台。如果我们编写一个脚本程序24小时不间断监听商品库存,一旦查询到货源便开始尝试自动下单,这样就可以极大提高我们的成功概率。

2 设计思路

京东对于商品的抢购主要分为两种:

预约抢购:到点开放购买,和普通商品下单流程一致;秒杀商品:单独的抢购接口和下单流程。

当然本次针对的预约抢购类或无货订购类,即整体下单流程和购买普通商品时一样:

登录账号 → 进入购物车 → 选择抢购商品 → 点击去结算 → 点击提交订单 → 选择付款方式并付款

3 具体实现

由于笔者本人没有一个可以抓包的客户端,决定采用京东 WEB 端接口实现我们的脚本程序。

于是经过对京东网页下单流程的分析,将我们的脚本程序分为四个模块:账号登录模块库存监听模块购物车管理模块订单管理模块。

3.1 账号登录

由于使用账号密码时有验证码限制,此处采用扫码登录方式绕过。

如对扫码登录不熟悉或感兴趣的同学可以查看周周之前的博文 扫码登录原理和实现。

本次只要针对京东登录页进行抓包分析,找到几个有用接口:

获取登录二维码

def getQRcode(self):
    url = 'https://qr.m.jd.com/show'
    payload = {
        'appid': 133,
        'size': 147,
        't': str(int(time.time() * 1000)),
    }
    headers = {
        'User-Agent': self.userAgent,
        'Referer': 'https://passport.jd.com/new/login.aspx',
    }
    resp = self.sess.get(url=url, headers=headers, params=payload)
 
    if not self.respStatus(resp):
        return None
 
    return resp.content

获取Ticket​​​​​​​

def getQRcodeTicket(self):
    url = 'https://qr.m.jd.com/check'
    payload = {
        'appid': '133',
        'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
        'token': self.sess.cookies.get('wlfstk_smdl'),
        '_': str(int(time.time() * 1000)),
    }
    headers = {
        'User-Agent': self.userAgent,
        'Referer': 'https://passport.jd.com/new/login.aspx',
    }
    resp = self.sess.get(url=url, headers=headers, params=payload)
 
    if not self.respStatus(resp):
        return False
 
    respJson = self.parseJson(resp.text)
    if respJson['code'] != 200:
        return None
    else:
        return respJson['ticket']

验证 Ticket​​​​​​​

def getQRcodeTicket(self):
    url = 'https://qr.m.jd.com/check'
    payload = {
        'appid': '133',
        'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
        'token': self.sess.cookies.get('wlfstk_smdl'),
        '_': str(int(time.time() * 1000)),
    }
    headers = {
        'User-Agent': self.userAgent,
        'Referer': 'https://passport.jd.com/new/login.aspx',
    }
    resp = self.sess.get(url=url, headers=headers, params=payload)
 
    if not self.respStatus(resp):
        return False
 
    respJson = self.parseJson(resp.text)
    if respJson['code'] != 200:
        return None
    else:
        return respJson['ticket']

此时验证 Ticket 有效后使用 pickle 库将程序会话中的 cookie 保存到本地以便下次使用。

3.2 库存监听

库存监听较为简单,分析商品详情页,获取店铺ID以及商品分类属性:

获取商品详情信息​​​​​​​

def getItemDetail(self, skuId):
    url = 'https://item.jd.com/{}.html'.format(skuId)
    page = requests.get(url=url, headers=self.headers)
 
    html = etree.HTML(page.text)
    vender = html.xpath(
        '//div[@class="follow J-follow-shop"]/@data-vid')[0]
    cat = html.xpath('//a[@clstag="shangpin|keycount|product|mbNav-3"]/@href')[
        0].replace('//list.jd.com/list.html?cat=', '')
 
    if not vender or not cat:
        raise Exception('获取商品信息失败,请检查SKU是否正确')
 
    detail = dict(catId=cat, venderId=vender)
    return detail

查询库存​​​​​​​

def getItemStock(self, skuId, num, areaId):
 
    item = self.itemDetails.get(skuId)
 
    if not item:
        return False
 
    url = 'https://c0.3.cn/stock'
    payload = {
        'skuId': skuId,
        'buyNum': num,
        'area': areaId,
        'ch': 1,
        '_': str(int(time.time() * 1000)),
        'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
        # get error stock state without this param
        'extraParam': '{"originid":"1"}',
        # get 403 Forbidden without this param (obtained from the detail page)
        'cat': item.get('catId'),
        # return seller information with this param (can't be ignored)
        'venderId': item.get('venderId')
    }
    headers = {
        'User-Agent': self.userAgent,
        'Referer': 'https://item.jd.com/{}.html'.format(skuId),
    }
 
    respText = ''
    try:
        respText = requests.get(
            url=url, params=payload, headers=headers, timeout=self.timeout).text
        respJson = self.parseJson(respText)
        stockInfo = respJson.get('stock')
        skuState = stockInfo.get('skuState')  # 商品是否上架
        # 商品库存状态:33 -- 现货  0,34 -- 无货  36 -- 采购中  40 -- 可配货
        stockState = stockInfo.get('StockState')
        return skuState == 1 and stockState in (33, 40)

3.3 购物车操作

无货商品加入到购物车我们是无法通过页面操作的,我们这边可以使用其他有货商品进行尝试,主要查看购物车的增删改查接口:

取消所有选中商品​​​​​​​

def uncheckCartAll(self):
    """ 取消所有选中商品
    return 购物车信息
    """
    url = 'https://api.m.jd.com/api'
 
    headers = {
        'User-Agent': self.userAgent,
        'Content-Type': 'application/x-www-form-urlencoded',
        'origin': 'https://cart.jd.com',
        'referer': 'https://cart.jd.com'
    }
 
    data = {
        'functionId': 'pcCart_jc_cartUnCheckAll',
        'appid': 'JDC_mall_cart',
        'body': '{"serInfo":{"area":"","user-key":""}}',
        'loginType': 3
    }
 
    resp = self.sess.post(url=url, headers=headers, data=data)
 
    # return self.respStatus(resp) and resp.json()['success']
    return resp

加入购入车​​​​​​​

def addCartSku(self, skuId, skuNum):
    """ 加入购入车
    skuId 商品sku
    skuNum 购买数量
    retrun 是否成功
    """
    url = 'https://api.m.jd.com/api'
    headers = {
        'User-Agent': self.userAgent,
        'Content-Type': 'application/x-www-form-urlencoded',
        'origin': 'https://cart.jd.com',
        'referer': 'https://cart.jd.com'
    }
    data = {
        'functionId': 'pcCart_jc_cartAdd',
        'appid': 'JDC_mall_cart',
        'body': '{\"operations\":[{\"carttype\":1,\"TheSkus\":[{\"Id\":\"' + skuId + '\",\"num\":' + str(skuNum) + '}]}]}',
        'loginType': 3
    }
    resp = self.sess.post(url=url, headers=headers, data=data)
    return self.respStatus(resp) and resp.json()['success']

修改购物车商品数量​​​​​​​

def changeCartSkuCount(self, skuId, skuUid, skuNum, areaId):
    """ 修改购物车商品数量
    skuId 商品sku
    skuUid 商品用户关系
    skuNum 购买数量
    retrun 是否成功
    """
    url = 'https://api.m.jd.com/api'
    headers = {
        'User-Agent': self.userAgent,
        'Content-Type': 'application/x-www-form-urlencoded',
        'origin': 'https://cart.jd.com',
        'referer': 'https://cart.jd.com'
    }
    body = '{\"operations\":[{\"TheSkus\":[{\"Id\":\"'+skuId+'\",\"num\":'+str(
        skuNum)+',\"skuUuid\":\"'+skuUid+'\",\"useUuid\":false}]}],\"serInfo\":{\"area\":\"'+areaId+'\"}}'
    data = {
        'functionId': 'pcCart_jc_changeSkuNum',
        'appid': 'JDC_mall_cart',
        'body': body,
        'loginType': 3
    }
    resp = self.sess.post(url=url, headers=headers, data=data)
    return self.respStatus(resp) and resp.json()['success']

以上是我们一次购买需要用到的最少接口,为了不破坏账户购物车中已有数据,采用一下步骤准备好购物车:

取消全部勾选(返回购物车信息);已在购物车则修改商品数量;不在购物车则加入购物车。3.4 订单操作

当我们准备好购物车之后(选中购买商品以及调整购买数量),就可以进行下一步订单相关操作:

获取结算单​​​​​​​

def getCheckoutPage(self):
    """获取订单结算页面信息
    :return: 结算信息 dict
    """
    url = 'http://trade.jd.com/shopping/order/getOrderInfo.action'
    # url = 'https://cart.jd.com/gotoOrder.action'
    payload = {
        'rid': str(int(time.time() * 1000)),
    }
    headers = {
        'User-Agent': self.userAgent,
        'Referer': 'https://cart.jd.com/cart',
    }

提交订单​​​​​​​

def submitOrder(self):
    """提交订单
    :return: True/False 订单提交结果
    """
    url = 'https://trade.jd.com/shopping/order/submitOrder.action'
    # js function of submit order is included in https://trade.jd.com/shopping/misc/js/order.js?r=2018070403091
 
    data = {
        'overseaPurchaseCookies': '',
        'vendorRemarks': '[]',
        'submitOrderParam.sopNotPutInvoice': 'false',
        'submitOrderParam.trackID': 'TestTrackId',
        'submitOrderParam.ignorePriceChange': '0',
        'submitOrderParam.btSupport': '0',
        'riskControl': self.risk_control,
        'submitOrderParam.isBestCoupon': 1,
        'submitOrderParam.jxj': 1,
        'submitOrderParam.trackId': self.track_id,
        'submitOrderParam.eid': self.eid,
        'submitOrderParam.fp': self.fp,
        'submitOrderParam.needCheck': 1,
    }

4 完整代码

项目完整源码请看:https://github.com/zas023/JdBuyer

目前完成度较高,可以直接使用:

并提供 Windows 和 macOS 两种客户端;支持下单后微信通知触达。

5 总结

脚本自动化操作确实可以实现抢购商品,相比手动操作有较高的下单成功率,但仅靠上述代码想与某些专业抢购的服务器进行比较还是相去甚远。

到此这篇关于教你用Python写一个京东自动下单抢购脚本的文章就介绍到这了!

最后: 下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取【保证100%免费】

在这里插入图片描述

 这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

教你用Python写一个京东自动下单抢购脚本(Python实现京东自动抢购) 的相关文章

  • VINS-Mono详解(1)——feature_tracker部分

    前言 视觉 IMU融合的优势 xff1a 1 视觉可以帮助IMU消除积分漂移和校正IMU的Bias xff1b 2 借助IMU可以帮助视觉系统提升输出频率 xff1b 3 IMU可帮助单目解决尺度不可观的问题 xff0c 帮助双目减少尺度上
  • Intel Realsense D455深度相机的标定及使用(二)——对内置IMU和双目相机进行标定

    标定前需先安装librealsense SDK2 0以及realsense ros xff0c 可参考教程 xff1a Intel Realsense D455深度相机的标定及使用 xff08 一 xff09 安装librealsense
  • 五、ROS学习之订阅T265里程计数据并与stm32通信

    使用ROS读出T265里程计数据 通过节点订阅t265的里程计数据1 订阅T265的里程计信息2 实现linux系统与stm32通信 xff0c 并向stm32发送里程计信息 通过节点订阅t265的里程计数据 我使用的是Kinetic版本
  • 在js文件中调用vue组件

    正常的书写一个vue组件 lt template gt lt div class 61 34 34 gt lt div gt lt template gt lt script gt export default name 39 Subscr
  • BMP180气压传感器详解与示例(STM32 附带源码)

    BMP180气压传感器详解与示例 xff08 STM32 附带源码 xff09 简介工作模式校准数值测试流程第一步 xff1a 微处理器读取校准数值第二步 xff1a 读取温度 气压初始值第三步 xff1a 计算温度 气压第四步 xff1a
  • MAX30102脉搏血氧仪和心率传感器(三)心率计算——时域法

    文章目录 前言一 算法思想二 算法详解1 阈值检测2 等待波形稳定3 FIR滤波 存入缓存区4 检测PPG信号与阈值曲线的交点5 心率计算 三 实际测试1 静止测试2 动态测试 四 总结五 获取工程源码 前言 本章介绍PPG信号的心率计算方
  • 基于51单片机的指纹密码锁设计

    目录 具体实现功能 设计介绍 单片机介绍 设计思路 资料内容 原理图 程序 仿真实现 全部资料 具体实现功能 具体功能 xff1a 本设计采用STC89C52 AT89C52 AT89S52作为主控芯片 xff0c LCD12864液晶显示
  • 基于51单片机的智能台灯设计

    具体实现功能 系统由STC89C52单片机 43 L数码管 43 光敏电阻 43 人体感应模块 43 红外接近传感器模块构成 具体功能 xff1a xff08 1 xff09 亮度不够且有人靠近时台灯自动亮 xff1b xff08 2 xf
  • pyharm快捷键说明

    官方文档 xff1a pycharm gt gt Help gt gt Keymap Reference 1 编辑 xff08 Editing xff09 Ctrl 43 Space 基本的代码完成 xff08 类 方法 属性 xff09
  • 基于51单片机超声波液位控制器设计

    具体实现功能 系统由AT89C52单片机 43 HC SR04超声波测距模块 43 LCD1602液晶屏 43 继电器 43 LED灯指示及蜂鸣器报警模块 43 按键模块 43 电源构成 具体功能 xff1a 1 由HC SR04超声波测距
  • 基于51单片机的电子密码锁设计

    目录 具体实现功能 设计背景 硬件设计 软件设计 原理图 程序 仿真实现 全部资料 具体实现功能 系统由AT89S52单片机 43 AT24C02数据存储模块 43 按键模块 43 LCD1602显示 43 报警模块等构成 具体功能 1 输
  • 基于51单片机智能热水器控制系统

    具体实现功能 系统由STC89C52单片机 43 水位检测传感器 43 DS18B20温度探头传感器 43 按键模块 43 继电器模块 43 报警及指示模块 43 LCD1602显示模块 43 电源构成 具体功能 xff1a 1 LCD16
  • 基于51单片机的火灾报警器

    具体实现功能 系统由51单片机 43 MQ 2烟雾传感 43 ADC0832模数转换芯片 43 DS18B20温度传感器 43 数码管显示 43 按键模块 43 声光报警模块构成 具体功能 xff1a 1 实时监测及显示温度值和烟雾浓度 x
  • 基于51单片机的步进电机控制系统

    具体实现功能 系统由STC89C52单片机 43 单体数码管 43 LED指示灯 43 ULN2003驱动芯片 43 DC 5V步进电机构成 具体功能 xff1a xff08 1 xff09 实现按键控制步进电机正转 反转 加速 减速 停止
  • 基于51单片机的数字时钟(万年历)

    具体实现功能 系统由STC89C52单片机 43 DS1302时钟芯片 43 按键模块 43 LCD1602显示 43 电源构成 具体功能 xff1a 1 可以显示年 月 日 时 分 秒 星期 农历 xff1b 2 按键可以设置闹钟及报警
  • 基于51单片机的排队叫号系统

    具体实现功能 系统由STC89C52单片机 43 按键模块 43 LCD1602液晶屏 43 蜂鸣器呼叫模块 43 电源构成 具体功能 xff1a 1 主机通过按键完成叫号 xff0c LCD1602液晶显示屏显示被叫的号码及服务的柜台号
  • 仿真设计|基于51单片机的简易抢答器

    目录 前言 具体实现功能 设计介绍 51单片机简介 设计方案 资料内容 仿真实现 xff08 protues8 7 xff09 程序 xff08 Keil5 xff09 全部资料 xff08 压缩文件 xff09 前言 全部资料包括程序 K
  • 实物设计|基于51单片机的温湿度检测报警系统

    目录 具体实现功能 xff1a 设计介绍 51单片机简介 设计方案 资料内容 原理图和PCB xff08 AD19 xff09 仿真实现 xff08 protues8 7 xff09 程序 xff08 Keil5 xff09 全部资料 xf
  • 设计分享|74LS148实现按键控制LED灯

    目录 具体实现功能 xff1a 设计介绍 51单片机简介 设计思路 设计内容 仿真图 xff08 protues8 7 xff09 程序 xff08 Keil5 xff09 具体实现功能 xff1a 74LS148实现按键控制LED灯 设计
  • 版本控制工具GIT and SVN 命令对比

    Git 安装 Debian Ubuntu OS Apt get install libcur14 gnutls dev libexppat1 dev gettext libz dev libssl dev Apt get install g

随机推荐

  • SUMO仿真教程(1) ——安装环境的设置(Windows 10系统)

    SUMO安装环境的设置 目录 一 SUMO下载的官方网址二 下载步骤 xff1a 三 环境设置 xff1a 1 打开设置环境变量的界面2 用户 xff08 Administrator xff09 变量设置3 系统变量设置 四 总述 一 SU
  • SUMO仿真教程(3)—— 仿真运行(net file、rou file、sumocfg file)

    文章目录 一 基本介绍 xff1a 1 简述 xff1a 二 文件说明 xff1a 1 路网文件 net xml 2 自定义编写路由文件 rou xml xff1a 3 生成运行仿真文件 sumocfg xff1a 4 进行运行仿真 xff
  • SUMO仿真教程(5) —— 使用“XML“语言自定义构建路网

    文章目录 一 简要介绍1 node file2 edge file3 lane definitions xff08 1 xff09 路段细分 xff08 2 xff09 邻近的对向车道 xff08 3 xff09 删除边或车道 4 type
  • SUMO仿真教程(7)—— 交通需求模型介绍

    文章目录 一 简要介绍 xff1a 二 方式一 xff1a 使用行程定义三 方式二 xff1a 使用交通流定义四 方式三 xff1a 使用随机流定义五 方式四 xff1a 使用OD矩阵定义六 方式五 xff1a 使用交叉口流量和转向比定义七
  • STM32 + UCOSII 操作系统(简单讲解)

    前言 这是我将UCOSII操作系统移植在STM32单片机上后进行UCOSII操作系统学习的一些笔记与理解 xff0c 此文最后会附上我自己在UCOSII操作系统下使用STM32写的ESP8266 43 onenet 43 http协议的程序
  • 地下水监测用设备 5G无线数传终端DTU

    地下水监测用设备5G无线数传终端DTU xff0c 实现地下水水位 温度 电导率 水质 孔隙压力等数据传输入库 远程采集 远程监测 曲线及报表可视化管理 地下水监测用5G无线数传终端DTU功能配置 地下水监测用5G无线数传终端负责连接前端采
  • 图解进程线程、互斥锁与信号量-看完不懂你来打我

    在上学的时候 xff0c 老师讲到进程与线程的时候可能是这样讲的 xff1a 进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程 xff0c 是操作系统进行资源分配和调度的一个独立单元 xff0c 是应用程序运行的载体 线程
  • MySQL最左匹配原则,道儿上兄弟都得知道的原则

    自MySQL5 5版本起 xff0c 主流的索引结构转为B 43 树 B 43 树的节点存储索引顺序是从左向右存储 xff0c 在检索匹配的时候也要满足自左向右匹配 目录 一 最左匹配原则的原理二 违背最左原则导致索引失效的情况三 查询优化
  • 在STM32下完成基于FreeRTOS的多任务简单程序

    一 为什么要学习 RTOS 在裸机系统中 xff0c 所有的程序基本都是自己写的 xff0c 所有的操作都是在一个无限的大循环里面实现 现实生活中的很多中小型的电子产品用的都是裸机系统 xff0c 而且也能够满足需求 但是为什么还要学习 R
  • 虚拟机连不上网问题及解决

    虚拟机联网主要涉及四个方面的配合 xff1a 网络和共享中心 xff08 物理机 xff09 虚拟网络编辑器 网络适配器 有线连接的更多设置 xff08 相关配置文件 xff09 网络和共享中心 xff1a 提示 xff1a 需要注意的点是
  • linux命令查看系统硬件的版本(dmidecode)

    dmidecode命令 可以让你在Linux系统下获取有关硬件方面的信息 dmidecode的作用是将DMI数据库中的信息解码 xff0c 以可读的文本方式显示 由于DMI信息可以人为修改 xff0c 因此里面的信息不一定是系统准确的信息
  • git 设置代理和取消代理

    本地开启VPN后 xff0c GIt也需要设置代理 xff0c 才能正常略过GFW xff0c 访问goole code等网站 设置如下 xff08 可复制 xff09 xff1a git config global https proxy
  • 上下文切换理解

    1 上下文的理解 上下文是指 xff0c 每次执行前 xff0c 都会使用需要依赖两个环境 xff0c 分别是CPU寄存器 xff08 cpu中容量小但是速度很快的内存 xff09 和程序计数器 xff08 cpu正在执行的程序位置或者是准
  • debian-11版本虚拟机无法登入root账号

    debian11创建虚拟机时我们设置了root账户密码 xff0c 然而在登入时却在未列出中无法登入root账户 xff0c 如图 1 我们登入普通账号 xff0c 这里不提权是无法保存文件的 enter 输入 i 进入编辑模式 在这个位置
  • 整数加减运算的二进制表示

    两位整数的加减都可看做 一个数加上另一个数 xff0c 首先我们要把数据的二进制表示转化成补码 xff0c 因为在计算机内部 xff0c 数据的加减是按补码进行运算的 A补 43 B补 61 A 43 B 补 xff08 mod 2 n 4
  • TCP服务器端、客户端通讯(赋源码)

    实现通讯 xff0c 我们首先要知道是怎么样的一个流程 xff0c 下图是我画的一个通讯流程图 xff1a 一 Linux服务器端 我是在Ubuntu20 04下进行的 xff0c 使用的是C 43 43 xff0c 引入头文件socket
  • 超详细正点原子STM32F429开发板视频教程笔记01

    文章目录 前言一 GPIO入门知识二 寄存器描述和配置方法1 GPIO寄存器 总结 前言 买了一块正点原子阿波罗stm32f429开发板 xff0c 趁暑假有空看看教学视频 xff0c 之前看过一部分所以从GPIO的原理和配置开始写笔记 提
  • 软件测试之项目总结全攻略

    在我们测试工作过程中 xff0c 由于公司业务发展 xff0c 快速迭代等原因 xff0c 我们遇到的项目以小项目居多 更新界面元素 xff0c 上个活动页 xff0c 优化一下原有的功能等等 xff0c 加上事情繁琐 xff0c 任务多
  • 简历中的项目经历可以怎么写?

    概述 工作这10多年来 xff0c 也经常做招聘的工作 xff0c 面试过的人超过50人次了 xff0c 而看过的候选人的简历则有几百份了 xff0c 但是清晰且能突出重点的简历 xff0c 确实很少遇到 这里基本可以说明一个问题 xff0
  • 教你用Python写一个京东自动下单抢购脚本(Python实现京东自动抢购)

    很多朋友都有网购抢购限量商品的经历 有时候蹲点抢怎么也抢不到 今天小编带你们学习怎么用Python写一个京东自动下单抢购脚本 以后再也不用拼手速拼网速啦 快来一起看看吧 1 问题背景 经过无数次抢购失败后 xff0c 发现商家会不定时的放出