教你用Python写一个京东自动下单抢购脚本(Python实现京东自动抢购)
很多朋友都有网购抢购限量商品的经历,有时候蹲点抢怎么也抢不到,今天小编带你们学习怎么用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%免费】
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章
- Python 实现自动导入缺失的库
- 第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能
- 第三百四十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—craw母版l创建自动爬虫文件—以及 scrapy item loader机制
- python之simplejson,Python版的简单、 快速、 可扩展 JSON 编码器/解码器
- 通过Python自动发邮件《生如夏花》
- Python:利用python代码编程实现将视频的avi格式转换为MP4格式
- Python:更改默认启动的python程序及其对应的安装包路径(更改pip的默认安装包的路径)图文教程之详细攻略
- Python之matplotlib:基于matplotlib库利用python语言实现一张画布显示多张图的多种方法
- Python:利用python语言绘制多个子图经典案例、代码实现之详细攻略
- Python语言学习:基于python五种方法实现使用某函数名【func_01】的字符串格式('func_01')来调用该函数【func_01】执行功能
- Wps:wps中excel表格数据整理常用技巧—利用wps表格实现自动填充等差数列然后预测数值、将python语言中的列表格式数据存为excel内
- 〖Python自动化办公篇⑲〗 - python实现邮件自动化 - 邮件发送
- 微信朋友圈自动点赞(Python代码实现)
- Python实现点选验证码识别, 模拟登陆小破站并自动发弹幕
- 爬虫学习(9):python 自动发送QQ邮箱
- 哈哈哈,用 Python 实现微信自动回复真香啊
- Python实现基于Optuna超参数自动优化的Catboost分类模型(CatBoostClassifier算法)项目实战
- python实现QQ自动发送消息
- Python编程:python面向对象
- python IDLE 背景修改 IDLE (Python GUI)
- python——使用readline库实现tab自动补全
- python基础===一行 Python 代码实现并行(转)
- python基础===pendulum '''Python datetimes made easy.'''
- python基础===Python 代码优化常见技巧
- 〖Python自动化办公篇⑲〗 - python实现邮件自动化 - 邮件发送
- 微信朋友圈自动点赞(Python代码实现)
- python+Potrace实现自动作画——程序员的浪漫