听说最近冰墩墩很火?那就带大家用Python写个抢购脚本吧

事情是这样子的,昨天有粉丝私信问我能不能写个脚本抢冰墩墩:
我寻思着这好像也不难吧,不就是写一个淘宝抢购的脚本么,于是加班加点写了一个,结果写完测试的时候发现官方的冰墩墩现在已经下架了,只有一些非官方的店在售卖,也不知道货是真的还是假的。不过脚本既然已经写完了,那还是上来分享一波吧。万一重新上架了大家还是可以用这个脚本抢购的,虽然我仔细看了一下,这吉祥物并不是我喜欢的风格,不然我肯定先自己抢到了再上来分享这个脚本。

废话不多说,让我们愉快地开始吧~

相关文件

需要源码的可以关注小编的公众号【Python日志】,或者在后台私信小编都可以的哟

开发工具

Python版本:3.7.8
相关模块:
DecryptLogin模块;
argparse模块;
requests模块;
pyttsx3模块;
prettytable模块;
以及一些python自带的模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

原理简介

首先,要抢购淘宝商品,肯定要先模拟登录淘宝,这里我们还是借助公众号之前开源的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)

发现返回的数据里是有我们需要的信息的:


在这里插入图片描述

因为请求这个接口的时候我的淘宝购物车是这样子的:


22.png

刚好是对应上的,说明我们抓到的接口没毛病,只需要进一步把我们需要的信息提取出来即可:

# 解析购物车信息
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</script>', 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"]}成功, 已为您自动提交订单, 请尽快前往淘宝完成付款')

最终淘宝里的效果如下:


44.png

运行的终端的效果类似这样:

在这里插入图片描述

当然这样提示的效果可能不明显,毕竟你不会一直盯着这个终端看,你可以加个语音提示,代码如下:

# 电脑语音提示
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

server酱配置地址如下:

http://sc.ftqq.com/3.version

ok,大功告成啦,完整源代码详见相关文件。

效果展示

使用方式:

usage: taobaosnap.py [-h] --interval INTERVAL [--key KEY]

淘宝抢购脚本

optional arguments:
  -h, --help           show this help message and exit
  --interval INTERVAL  抢购商品时查询商品是否可以购买的时间间隔(单位秒)
  --key KEY            Server酱的Key

效果如下:

在这里插入图片描述

在这里插入图片描述

server酱的通知效果如下:
在这里插入图片描述

OK,今天的代码就到这里结束了,要是有小伙伴看不懂的话,或者需要源码的都可以私信小编的哈,或者关注小编的公众号【Python日志】,可以了领取的哈

大家记得给小编点赞+关注哟

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容