直接进入正文。京东抢购模式有很多种。
- 普通商品无货,定时查询库存蹲抢
- 普通商品定时发售(库存由0变为有货),定时提前构造订单请求抢
- 预售商品(需要先预约),可以加入购物车,通过购物车结算。这种用常规购物车结算订单接口就行,当然也可以用抢购接口。
这种体现为可以加购,抢购时候显示两个按钮,加入购物车(黄色)和立即购买(淡绿色)。
- 预售商品(需要先预约),无法加入购物车,电脑端无法预约,必须手机端预约。这种采用marathon.jd.com/seckillnew/... 接口完成抢购,有完整流程验证和tokenKey(sign),sk验证。
这种体现为 无法加入购物车,必须手机端才能预约,可购买时候只显示一个红色按钮立即抢购
逻辑参考GitHub大佬给出的思路。
第一步:获取跳转链接
跳转链接是指形如:un.m.jd.com/cgi-bin/app... 的链接,获取该链接,还需要一个前置步骤,即获取token和拼接url。先说获取token,获取token是通过genToken接口获取的,然后将获取到的tokenKey和url拼接起来,得到跳转链接。
第二步:访问跳转链接
拿到跳转链接后,直接将该跳转链接仍给浏览器即可,浏览器会经过两次302跳转得到sekill.action链接,从而渲染出提交订单页面,此时我们需要模拟点击"提交订单"按钮,实现抢购。(可以使用Selenium、Pyppeteer或Playwright等类库 来模拟浏览器)
访问跳转连接,及提交订单的时候需要提供移动端的APP参数抓包获取
。Android抓包较为简单,IOS的也不麻烦,就是步骤多了一些。
然后提取Hades头的信息组成以下参数
python
query_params = {
"functionId": "genToken",
"clientVersion": "12.0.8",
"build": "168782",
"client": "apple",
"d_brand": "apple",
"d_model": "iPhone11,4",
"osVersion": "16.5",
"screen": "1284*2778",
"partner": "apple",
"aid": self.aid,
"eid": self.eid,
"sdkVersion": "29",
"lang": "zh_CN",
# 'harmonyOs': '0',
"uuid": self.uuid,
"area": "4_51026_58465_0",
"networkType": "wifi",
"wifiBssid": self.wifiBssid,
"uts": self.uts,
"uemps": "0-0-0",
"ext": '{"prstate":"0","pvcStu":"1"}',
# 'ef': '1',
# 'ep': json.dumps(ep, ensure_ascii=False, separators=(',', ':')),
}
这种仅仅是前面所需的参数。具体方法还是需要使用这些参数来获取用户的个人信息拿到跳转连接
如:
python
def get_appjmp(self, token_params):
headers = {"user-agent": self.ua}
appjmp_url = token_params["url"]
params = {
"to": "https://divide.jd.com/user_routing?skuId=%s" % self.skuId,
"tokenKey": token_params["tokenKey"],
}
response = self.s.get(
url=appjmp_url,
params=params,
allow_redirects=False,
verify=False,
headers=headers,
)
print("Get Appjmp跳转链接-------------->%s" % response.headers["Location"])
return response.headers["Location"]
get_appjmp(self, token_params)
函数接受一个名为 token_params
的参数。
然后发送相关请求后携带参数得到跳转链接。
-
headers
是一个字典,包含了请求头中的 "User-Agent" 字段,用于模拟浏览器的用户代理。 -
appjmp_url
是一个变量,它存储了token_params
字典中的 "url" 键所对应的值。 -
params
是一个字典,其中包含两个键值对: -
"to" 键对应的值是一个字符串,使用了
%s
占位符,用于生成跳转链接中的skuId
参数。 -
"tokenKey" 键对应的值是一个字符串,使用了
token_params
字典中的 "tokenKey" 键所对应的值。 -
通过调用
self.s.get()
方法发起一个 GET 请求,传入以下参数: -
url
参数是appjmp_url
,表示要访问的链接地址。 -
params
参数是之前定义的params
字典,用于添加请求参数。 -
allow_redirects
参数设置为False
,禁止自动重定向。 -
verify
参数设置为False
,跳过 SSL 证书验证。 -
headers
参数是之前定义的headers
字典,用于设置请求头。 -
最后,打印获取到的跳转链接的响应头中的 "Location" 字段值,并将其返回。
抢购返回解决无非就是
{'errorMessage': '很遗憾没有抢到,再接再厉哦。', 'orderId': 0, 'resultCode': 90016, 'skuId': 0, 'success': False}
{'errorMessage': '很遗憾没有抢到,再接再厉哦。', 'orderId': 0, 'resultCode': 90008, 'skuId': 0, 'success': False}
根据其他作者的推测 推测返回 90008 是京东的风控机制,代表这次请求直接失败,不参与抢购。
小白信用越低越容易触发京东的风控。
具体代码可参考GitHub地址
感谢GitHub作者@geeeeeeeek @jd-seckill等