前言
今天带你官方的冰墩墩淘宝抢购脚本
让我们愉快地开始吧~
开发工具
Python版本: 3.6.4
相关模块:
DecryptLogin模块;
argparse模块;
requests模块;
pyttsx3模块;
prettytable模块;
以及一些python自带的模块。
环境搭建
首先,要抢购淘宝商品,肯定要先模拟登录淘宝,这里我们还是借助公众号之前开源的DecryptLogin包:
项目地址:https://github.com/CharlesPikachu/DecryptLogin安装:pip install DecryptLogin
具体而言,代码实现如下:
from DecryptLogin import login
'''模拟登录'''
def login(self):
lg = login.Login()
infos_return, session = lg.taobao()
return infos_return, session
接着,我们来考虑一下如何获得想要抢购的商品的信息,是不是可以直接添加到购物车,然后通过查询购物车信息来获得我们想要抢购的商品信息呢?写个代码简单测试一下:
'''获得购物车信息'''
def buycartinfo(self):
url = 'https://cart.taobao.com/cart.htm'
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'sec-fetch-dest': 'document', 'sec-fetch-mode': 'navigate', 'sec-fetch-site': 'none', 'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'cache-control': 'max-age=0'
}
response = self.session.get(url, headers=headers)
print(response.text)
发现返回的数据里是有我们需要的信息的:
因为请求这个接口的时候我的淘宝购物车是这样子的:
刚好是对应上的,说明我们抓到的接口没毛病,只需要进一步把我们需要的信息提取出来即可:
# 解析购物车信息
if len(cart_infos['list']) == 0:
raise RuntimeError('购物车是空的, 请在购物车中添加需要抢购的商品')
good_infos = {}
for idx, item in enumerate(cart_infos['list']):
good_info = {
'title': item['bundles'][0]['orders'][0]['title'],
'cart_id': item['bundles'][0]['orders'][0]['cartId'],
'cart_params': item['bundles'][0]['orders'][0]['cartActiveInfo']['cartBcParams'], 'item_id': item['bundles'][0]['orders'][0]['itemId'],
'sku_id': item['bundles'][0]['orders'][0]['skuId'],
'seller_id': item['bundles'][0]['orders'][0]['sellerId'],
'to_buy_info': item['bundles'][0]['orders'][0]['toBuyInfo'],
}
good_infos[str(idx)] = good_info
# 打印并选择想要抢购的商品信息
title, items = ['id', 'title'], []
for key, value in good_infos.items():
items.append([key, value['title']])
self.printTable(title, items)good_id = input('请选择想要抢购的商品编号(例如"0"): ')
assert good_id in good_infos, '输入的商品编号有误'
效果大概是这样的:
用户根据抓取到的自己购物车中的已有的商品信息来选择自己想要抢购的商品(即,如果你想要抢购某件商品,你需要先把它加入自己的购物车中)。接下来,我们需要考虑的就是如何抢购选中的商品了。具体而言,购买商品的代码实现如下:
'''购买商品'''
def buygood(self, info, user_id):
# 发送结算请求
url = 'https://buy.taobao.com/auction/order/confirm_order.htm?spm=a1z0d.6639537.0.0.undefined'
headers = {
'cache-control': 'max-age=0', 'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'origin': 'https://cart.taobao.com', 'content-type': 'application/x-www-form-urlencoded',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'sec-fetch-site': 'same-site', 'sec-fetch-mode': 'navigate', 'sec-fetch-user': '?1',
'sec-fetch-dest': 'document', 'referer': 'https://cart.taobao.com/',
'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8'
}
cart_id, item_id, sku_id, seller_id, cart_params, to_buy_info = info['cart_id'], info['item_id'], info['sku_id'], info['seller_id'], info['cart_params'], info['to_buy_info']
data = {
'item': f'{cart_id}_{item_id}_1_{sku_id}_{seller_id}_0_0_0_{cart_params}_{urllib.parse.quote(str(to_buy_info))}__0',
'buyer_from': 'cart',
'source_time': ''.join(str(int(time.time() * 1000)))
}
response = self.session.post(url = url, data = data, headers = headers, verify = False)
order_info = re.search('orderData= (.*?);\n', response.text).group(1)
order_info = json.loads(order_info)
# 发送提交订单请求
token = self.session.cookies['_tb_token_']
endpoint = order_info['endpoint']
data = order_info['data']
structure = order_info['hierarchy']['structure']
hierarchy = order_info['hierarchy']
linkage = order_info['linkage']
linkage.pop('url')
submitref = order_info['data']['submitOrderPC_1']['hidden']['extensionMap']['secretValue']
sparam1 = order_info['data']['submitOrderPC_1']['hidden']['extensionMap']['sparam1']
input_charset = order_info['data']['submitOrderPC_1']['hidden']['extensionMap']['input_charset']
event_submit_do_confirm = order_info['data']['submitOrderPC_1']['hidden']['extensionMap']['event_submit_do_confirm']
url = f'https://buy.taobao.com/auction/confirm_order.htm?x-itemid={item_id}&x-uid={user_id}&submitref={submitref}&sparam1={sparam1}'
data_submit = {}
for key, value in data.items():
if value.get('submit') == 'true' or value.get('submit'):
data_submit[key] = value
data = {
'action': '/order/multiTerminalSubmitOrderAction',
'_tb_token_': token,
'event_submit_do_confirm': '1',
'praper_alipay_cashier_domain': 'cashierrz54',
'input_charset': 'utf-8',
'endpoint': urllib.parse.quote(json.dumps(endpoint)),
'data': urllib.parse.quote(json.dumps(data_submit)),
'hierarchy': urllib.parse.quote(json.dumps({"structure": structure})),
'linkage': urllib.parse.quote(json.dumps(linkage))
}
headers = {
'cache-control': 'max-age=0', 'upgrade-insecure-requests': '1', 'origin': 'https://buy.taobao.com',
'content-type': 'application/x-www-form-urlencoded',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'navigate', 'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',
'referer': 'https://buy.taobao.com/auction/order/confirm_order.htm?spm=a1z0d.6639537.0.0.undefined',
'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8'
}
response = self.session.post(url, data=data, headers=headers)
if response.status_code == 200: return True
return False
抢购的逻辑如下,即每隔一段时间尝试购买一次商品,直到成功为止:
# 根据选择尝试购买商品
print(f'[INFO]: 正在尝试抢购商品{good_infos[good_id]["title"]}')
while True:
try:
is_success = self.buygood(good_infos[good_id], user_id)
except:
is_success = False
if is_success: break
time.sleep(self.trybuy_interval)
print(f'[INFO]: 抢购{good_infos[good_id]["title"]}成功, 已为您自动提交订单, 请尽快前往淘宝完成付款')
最终淘宝里的效果如下:
运行的终端的效果类似这样:
当然这样提示的效果可能不明显,毕竟你不会一直盯着这个终端看,你可以加个语音提示,代码如下:
# 电脑语音提示
for _ in range(5):
pyttsx3.speak('已经为您抢购到你所需的商品, 请尽快前往淘宝完成付款.')
本文源码及打包程序详见个人主页简介获取
当然,也许你也不一定一直在电脑边上,所以你还可以加个server酱提示,可以在商品抢购成功之后将该消息发送到你的微信上,代码如下:
'''发送Server酱提示'''
def pushwechat(self, desp='已经为您抢购到你所需的商品, 请尽快前往淘宝完成付款.'):
server_url = f'https://sc.ftqq.com/{self.server_key}.send'
params = {
'text': '商品抢购成功提示',
'desp': desp,
}
response = requests.get(server_url, params=params)
return response