教你用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写一个京东自动下单抢购脚本的文章就介绍到这了!

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群: 320231853,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

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

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 一个自动抢购京东茅台的脚本需要以下步骤: 1. 打开京东茅台商品页面,确定你想要抢购的商品的 URL。 2. 使用 Python 的网络爬虫模块,例如 requests 库,来爬取商品页面的 HTML 代码。 3. 解析 HTML 代码,找到抢购按钮的位置。 4. 使用 Python自动化测试模块,例如 selenium,来模拟点击抢购按钮。 5. 设置一个循环,不断检查商品是否已经抢购成功。如果成功,退出循环;如果未成功,继续循环。 下面是一个简单的示例代码: ```python import time from selenium import webdriver # 打开浏览器 driver = webdriver.Chrome() # 访问商品页面 driver.get("商品页面 URL") while True: # 点击抢购按钮 driver.find_element_by_css_selector("抢购按钮的 CSS 选择器").click() # 检查是否抢购成功 result = driver.find_element_by_css_selector("抢购结果的 CSS 选择器").text if result == "抢购成功": print("抢购成功!") break else: print("抢购未成功,继续尝试...") # 等待一段时间再继续尝试 time.sleep(1) # 关闭浏览器 driver. ### 回答2: 使用Python一个自动抢购京东茅台的脚本有以下步骤: 1. 导入相关的模块,如selenium和webdriver,用于实现自动化操作。 2. 设置浏览器驱动,如ChromeDriver,确保能在代码中对浏览器进行控制。 3. 打开京东网站,并登录账号。 4. 进入茅台商品页面,获取抢购按钮的位置和状态。 5. 判断抢购按钮的状态,如果是可点击状态,则点击抢购按钮。 6. 进入结算页面,选择收货地址、支付方式等相关信息。 7. 确认订单并完成支付。 上述步骤中,一般比较关键的是第4步和第5步。在第4步中,需要通过网页元素定位的方式找到抢购按钮,并获取其状态信息,常用的定位方式有XPath和CSS选择器。在第5步中,需要判断抢购按钮的状态,如果是可点击状态,则调用点击操作,实现抢购功能。 在编脚本时,可以结合selenium的API文档和浏览器开发者工具来查找和定位页面元素,以及了解元素的属性和状态。此外,还可以使用隐式等待或显式等待来确保页面加载完毕后再进行操作,避免因页面未加载完而导致的错误。 需要注意的是,使用自动脚本抢购商品可能会违反京东的使用规定,甚至涉及到法律问题。因此,在实际操作中应遵循相关法律法规和京东的规定,建议合法合规地使用自动脚本,并确保不会对他人造成不公平竞争或恶意利用的影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值