白酒

python使用requests秒杀茅台(适用某宝,也可抢购其他商品)

作者:admin 2024-11-30 我要评论

文章浏览阅读6.7k次,点赞18次,收藏101次。1、登录2、requests请求“确认订单”所需信息3、requests请求“提交订单”_淘宝抢茅台代码...

前言

关于茅台抢购,看过不下一百篇小文章,浏览来浏览去,也找不到几篇合适的。虽然有很多人发布了使用selenium抢购茅台的脚本,但个人觉得这些没有直接使用requests提交订单来的快。于是!就有了你现在读的文章!废话不多说,开搞!

准备工作

安装python,这就不用我说吧?至于开发工具使用什么看自己心情,我这里使用的是vscode,不知道如何操作的可以参考这位博主的。这位博主的文章下面还有selenium的安装教程,可以顺便看一下,因为我这里也要用到selenium登录,我就不重复造轮子了。

分析一波抢购流程

1、登录

2、requests请求“确认订单”所需信息

3、requests请求“提交订单”

看似简单的三步,我可花费了好多心血来研究啊,得掉多少头发!

具体实现过程

import re, time, random, datetime, sys, requests, threading, psutil
from requests.cookies import RequestsCookieJar
from selenium.webdriver.common.by import By
from multiprocessing import Queue
from urllib.parse import quote
from selenium import webdriver
from io import BytesIO
from PIL import Image
class Login():
    def __init__(self):
        #设置关键词进行匹配或判断,下同
        self.key_word1 = '账号管理'
        self.key_word2 = '安全链接'
        self.j = 0
        #创建队列存放post订单结果
        self.queue = Queue(maxsize=100)
        # 创建Session对象  requests库的session对象会在同一个session实例的所有请求之间使用cookies保持登录状态
        self.session = requests.session()
        #设置headers
        ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.50"
        self.headers = {
            'User-Agent': ua
        }
        self.session.headers.update(self.headers)
    # 扫码登录,获取cookies
    def get_cookies(self):
        options = webdriver.ChromeOptions()
        options.add_experimental_option('excludeSwitches', ['enable-logging'])
        options.add_argument('--headless')
        browser = webdriver.Chrome(options=options)
        url = 'https://login.taobao.com/member/login.jhtml'
        browser.get(url)
        # 点击跳转扫码界面
        browser.find_element(By.XPATH,'/html/body/div[1]/div[2]/div[3]/div/div/div/div[1]/i').click()
        time.sleep(round(random.uniform(1,2),2))
        # 获取并保存二维码截图
        qrcode_img_data=browser.find_element(By.XPATH, '//*[@id="login"]/div[2]/div/div[1]/div[1]').screenshot_as_png
        qrcode_img = Image.open(BytesIO(qrcode_img_data))
        qrcode_img.save('qrcode.png')
        qrcode_img.show()
        print("请扫码登录!")
        time.sleep(2)
        # 每隔1.5秒判断一次是否登录成功
        t=0
        while t < 40:
            try:
                info = browser.find_element(By.XPATH, '//*[@id="J_Col_Main"]/div/div[1]/div/div[1]/div[1]/div/div[1]/a/em').text
                print('您的帐户:' + info)
                for proc in psutil.process_iter():  # 遍历当前process
                    if proc.name() == "Microsoft.Photos.exe":
                        proc.kill()  # 关闭该process
                break
            except:
                time.sleep(1.5)
                t+=1
        # 获取Cookie并保持在session中
        cookies = browser.get_cookies()
        time.sleep(round(random.uniform(1,2),2))
        browser.quit()
        selenium_cookies = cookies
        tmp_cookies = RequestsCookieJar()
        for item in selenium_cookies:
            tmp_cookies.set(item["name"], item["value"])
        self.session.cookies.update(tmp_cookies)
    #登录
    def login(self):
        print("登录中...")
        try:
            req=self.session.get('https://i.taobao.com/user/baseInfoSet.htm?').text
            if self.key_word1 in req:
                print("自动登录成功!")
            else:
                print("自动登录失败!\n请再次扫码登录!")
                self.get_cookies()
                self.session.get('https://i.taobao.com/user/baseInfoSet.htm?').text
                if self.key_word1 in req:
                    print("自动登录成功!")
                else:
                    print("自动登录失败!\n请手动完成该任务")
                    sys.exit(0)
        except:
            print('程序出错!')
            sys.exit(0)
    # 提交订单
    def submitOrder(self, url, skuId, setTime, quantity):
        self.url = url
        quantity = '_' + quantity + '_'
        # 获取cookies并登录
        self.cookies=self.get_cookies()
        self.login()
        time.sleep(round(random.uniform(1,2),2))
        # 进入商品详情页 
        self.req = self.session.get(url=self.url).text
        time.sleep(round(random.uniform(1,2),2))
        # 提取 key datas
        self.patterGoods()
        time.sleep(round(random.uniform(1,2),2))
        # 确认订单
        data = {
            "buy_param": self.auction[0] + quantity + skuId
        }
        url = 'https://buy.tmall.com/order/confirm_order.htm?x-itemid=' + self.auction[0] + '&x-uid=' + self.userId[0]
        k = 0
        while True:
            print("\r购买倒计时:%.3f"%(setTime-time.time()),end="",flush=True)
            if (time.time() >= setTime):
                print('\n')
                print(datetime.datetime.now())
                while True:
                    self.req = self.session.post(url=url, data=data).text
                    # 获取数据
                    key = self.patterData()
                    k+=1
                    if(k==50):
                        print("\n确认订单失败!下次加油哦")
                        print(datetime.datetime.now())
                        sys.exit(0)
                    if(key):
                        print("\n确认订单成功!")
                        print(datetime.datetime.now())
                        break
                break
        # 提交订单
        data = {
            "endpoint": self.endpoint,
            "linkage": self.linkage,
            "data": self.data,
            "action": self.action,
            "_tb_token_": self.tbToken,
            "event_submit_do_confirm": self.event,
            "praper_alipay_cashier_domain": self.unitSuffix,
            "input_charset": self.charset,
            "hierarchy": self.hierarchy
        }
        url = 'https://buy.tmall.com/auction/confirm_order.htm?x-itemid=' + self.auction[0] + '&x-uid=' + self.userId[0] + '&submitref=' + self.submitUrl
        #多线程,提高抢购效率
        thread_list=[]
        for i in range(1,80):
            t = threading.Thread(target=self.post, args=(url, data))
            thread_list.append(t)
        l = len(thread_list)
        # 启动线程
        for i in range(0,l-1):
            thread_list[i].start()
        # 关闭线程
        for t in range(0,l-1):
            thread_list[i].join()
        while self.queue.empty() == False:
            req = self.queue.get()
            if self.key_word2 in req:
                print('提交订单成功!请快尽快付款!')
                self.j = 1
                break
        if self.j == 0:
            print('提交订单失败!请下次重试!')
        print('Buy End!')
        sys.exit(0)
    # 提取信息:商品详情
    def patterGoods(self):
        # 页面id
        self.auction=re.findall(r'(?<=auction=).*?(?=&)', self.req)
        # 用户id
        self.userId=re.findall(r'(?<=&userid=).*?(?=&)', self.req)
        # 购买端token
        tbTokens=re.findall(r'(?<=yunid=&).*?(?=&)', self.req)
        self.tbToken = tbTokens[0]
    # 提取信息:生成订单数据
    def patterData(self):
        # 正则匹配
        data=re.findall(r'(?<="secretValue":).*?(?=,"unitSuffix")', self.req)
        if not data:
            return False    
        self.submitUrl = ''.join(data)
        self.submitUrl=re.sub(r'"', '', self.submitUrl)
        self.submitUrl=re.sub(r',', '&', self.submitUrl)
        self.submitUrl=re.sub(r':', '=', self.submitUrl)
        data = re.findall(r'(?<="endpoint":).*?(?=,"data")', self.req)
        self.endpoint = ''.join(data)
        self.endpoint = quote(self.endpoint)
        data = re.findall(r'(?<="action":").*?(?=","event_submit_do_confirm")', self.req)
        self.action = ''.join(data)
        data = re.findall(r'(?<="event_submit_do_confirm":").*?(?=","input_charset")', self.req)
        self.event = ''.join(data)
        data = re.findall(r'(?<="input_charset":").*?(?=","pcSubmitUrl")', self.req)
        self.charset = ''.join(data)
        data = re.findall(r'(?<="unitSuffix":").*?(?="}},)', self.req)
        unitSuffix = ''.join(data)
        self.unitSuffix = "cashier" + unitSuffix
        data=re.findall(r'(?<="data":).*?(?=,"linkage")', self.req)
        self.data = ''.join(data)
        self.data = quote(self.data)     # url 编码
        data=re.findall(r'(?<="linkage":).*?(?=,"hierarchy")', self.req)
        self.linkage = ''.join(data)
        self.linkage = quote(self.linkage)
        data=re.findall(r'(?<="hierarchy":).*?(?=,"container")', self.req)
        self.hierarchy = ''.join(data)
        self.hierarchy = quote(self.hierarchy)
        return True
    def post(self, url, data):
        req = self.session.post(url=url, data=data).text
        self.queue.put(req)

也就……也就一两百行代码吧,当然这些代码也不是完完全全由我敲出来的,我只是站在巨人的肩膀上(doge)

这不是全部的代码,还有还有……

from TTime import postTime
import TbMoudle, time
if __name__ == "__main__":
    # 商品链接
    #url = 'https://detail.tmall.com/item.htm?id=576148466933&spm=a1z09.2.0.0.28032e8dcv63yd&_u=1340hb4c2d7d&skuId=4516861399500'            #用来测试的淘宝链接,通过
    url = 'https://chaoshi.detail.tmall.com/item.htm?id=20739895092&spm=a1z0k.7628870.0.0.6d8537de1tkYdk&_u=t2dmg8j26111&skuId=4227830352490'           #茅台链接
    #url = 'https://chaoshi.detail.tmall.com/item.htm?spm=a1z0d.6639537/tb.1997196601.3.52367484NWZmwA&id=541462757234&skuId=5029227863773'            #用来测试的天猫链接,通过
    '''
    #设定抢购物品的url
    #详情页网址是用电脑登录,选好数量和样式之后的网址
    url=str(input("请输入详情页网址:\n"))
    '''
    # 仅适用于 skUid 在链接末  即已选好商品规格的链接
    skuIds = url.split('=')
    k = len(skuIds)-1
    skuId = skuIds[k]
    quantity = '1'          # 购买数量
    # 定时 + 毫秒延迟校正
    action_time='20:00:00'
    post_date = time.strftime("%Y/%#m/%#d",time.localtime(time.time()))
    post_time = post_date + ' ' + action_time
    setTime = postTime(post_time) - 0.2
    # 实例化对象 
    a = TbMoudle.Login()
    a.submitOrder(url, skuId, setTime, quantity)

还有一段,是上面这段代码所需的模块之一!

import time
# 输入触发时间 返回时间戳
def postTime(setTime):
    #转换成时间数组
    timeArray = time.strptime(setTime, "%Y/%m/%d %H:%M:%S")
    #转换成时间戳
    timestamp = time.mktime(timeArray)
    return timestamp

ok,全部代码都在上面了,有时间会打包放在github上面,后面再更!别催!还有不要忘记安装第二段代码所需依赖!依赖放在下面了!一个一个装吧,哈哈!

Pillow==9.3.0
psutil==5.9.1
requests==2.28.1
selenium==4.5.0

说明

第一段代码copy下来命名为TbMoudle.py,第二段命名为main.py(随便命名也行),第三段命名为TTime.py,然后运行第二段代码即可。想要抢购茅台,在19:55左右运行main.py,过几秒会出现二维码,60秒内使用淘宝扫码即可(不要问我为什么不用保存的cookies登录,问就是不方便)。虽然到现在我还没有抢到过,但一定不是我的代码的问题吧?对吧???嗯???

参考

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • “高仿”版茅台、五粮液公然叫卖:“一

    “高仿”版茅台、五粮液公然叫卖:“一

  • 喜提“三级演员”后,嘎子哥谢孟伟直言

    喜提“三级演员”后,嘎子哥谢孟伟直言

  • 五粮液酒有哪些?盘点全系列十款五粮液

    五粮液酒有哪些?盘点全系列十款五粮液

  • a货五粮液在哪里买?白酒批发商的采购

    a货五粮液在哪里买?白酒批发商的采购