某宝秒杀活动脚本

taobo.py

import json
from time import sleep
from datetime import datetime

from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from utils.utils import notify_user
from utils.utils import build_chrome_options

# 抢购失败最大次数
max_retry_count = 30


# 自动抢票类(淘宝)
class TaoBao:

    def __init__(self, chrome_path="./chromedriver.exe", seckill_time_str=None, password=None):
        # 驱动路径
        self.chrome_path = chrome_path
        # 抢购时间
        self.seckill_time = datetime.strptime(seckill_time_str, '%Y-%m-%d %H:%M:%S')
        # 支付密码
        self.password = password
        # chrome驱动
        self.driver = None

    # 获取chrome驱动
    def start_driver(self):
        try:
            driver = self.find_chromedriver()
        except WebDriverException:
            print("Unable to find chromedriver, Please check the drive path.")
        else:
            return driver

    # 寻找chrome驱动(首先去python安装目录下找,其次再去传入的路径找)
    def find_chromedriver(self):
        try:
            driver = webdriver.Chrome()
        except WebDriverException:
            try:
                driver = webdriver.Chrome(executable_path=self.chrome_path, chrome_options=build_chrome_options())
            except WebDriverException:
                raise Exception("Unable to find chromedriver, Please check the drive path.")
        return driver

    # 登录淘宝
    def login(self, login_url="https://www.taobao.com", login_time_out=10):
        if login_url:
            self.driver = self.start_driver()
        else:
            raise Exception("Please input the login url.")
        while True:
            # 打开首页
            self.driver.get(login_url)
            try:
                # 尝试获取点击登录超链接
                a_lists = self.driver.find_elements(By.XPATH, '//div[@class="site-nav-sign"]/a')
                # 获取到了,说明还未登录,进行登录
                if len(a_lists) > 0:
                    print("没登录,开始点击登录按钮...")
                    # 亲,请登录
                    login_button = a_lists[0]
                    login_button.click()
                    print("请在{}s内扫码登陆!!".format(login_time_out))
                    # 睡眠login_time_out(s)
                    sleep(login_time_out)
                    # 尝试获取登录成功页面的元素,找到了表示已经登录成功。
                    if self.driver.find_element(By.XPATH, '//*[@id="J_SiteNavMytaobao"]/div[1]/a/span'):
                        print("登陆成功")
                        # 进入购物车
                        self.driver.get("https://cart.taobao.com/cart.htm")
                        # 结束循环
                        break
                    else:
                        print("登陆失败, 刷新重试, 请尽快登陆!!!")
                        continue
            except Exception as e:
                print(str(e))
                continue

    # 等待抢购
    def keep_wait(self):
        print("等待到点抢购...")
        while True:
            # 获取当前时间
            current_time = datetime.now()
            # 如果距离抢购时间大于3分钟,则每分钟刷新一次界面,防止登录超时。
            if (self.seckill_time - current_time).seconds > 180:
                # 进入购物车
                self.driver.get("https://cart.taobao.com/cart.htm")
                print("每分钟刷新一次界面,防止登录超时...")
                sleep(60)
            else:
                # 调用函数,将浏览器cookie写入文件备用。
                self.get_cookie()
                print("抢购时间点将近,停止自动刷新,准备进入抢购阶段...")
                # 抢购时间将近,结束等待抢购
                break

    # 抢购的入口函数
    def sec_kill(self, login_time_out=15):
        print("此次抢购时间:{}".format(datetime.strftime(self.seckill_time, "%Y-%m-%d %H:%M:%S")))
        # 调用登录函数
        self.login(login_time_out=login_time_out)
        # 调用等待抢购函数
        self.keep_wait()

        # 获取全选框
        select_all = self.driver.find_element(By.ID, "J_SelectAll1")
        if select_all:
            print("当前未选状态,自动选择全部商品")
            # 点击全选
            select_all.click()
        print("已经选中全部商品!!!")

        # 记录提交状态
        submit_success = False
        # 重试抢购次数
        retry_count = 0

        while True:
            # 获取当前时间
            now = datetime.now()
            if now >= self.seckill_time:
                print(f"开始抢购, 尝试次数: {str(retry_count + 1)}")
            else:
                # 睡眠一段时间,防止cpu一直工作
                sleep(0.1)
                continue
            try:
                # 等待结算按钮可以被点击
                button = WebDriverWait(self.driver, 5, poll_frequency=0.1).until(
                    EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_SmallSubmit')))
                # 点击结算
                button.click()
                print("已经点击结算按钮...")
                # 等待跳转到提交订单按钮可以被点击
                submit = WebDriverWait(self.driver, 5, poll_frequency=0.1).until(
                    EC.element_to_be_clickable((By.CSS_SELECTOR, '#submitOrderPC_1 > div > a.go-btn')))
                # 点击提交订单
                submit.click()
                print("已经点击提交订单按钮...")
                # 记录提交状态
                submit_success = True
                # 退出循环
                break
            except Exception as e:
                print(e)
                print("临时写的脚本, 可能出了点问题!!!")
                retry_count += 1
                if retry_count > max_retry_count:
                    print("重试抢购次数达到上限,放弃重试...")
                    break
        # 提交成功,准备支付
        if submit_success:
            if self.password:
                self.pay()

    def pay(self):
        try:
            # 等待密码框加载完毕
            element = WebDriverWait(self.driver, 5).until(
                EC.presence_of_element_located((By.CLASS_NAME, 'sixDigitPassword')))
            # 输入密码
            element.send_keys(self.password)
            print("密码输入完成")
            # 等待确认付款按钮加载完成,并付款
            WebDriverWait(self.driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#J_authSubmit'))).click()
            print("付款成功")
            notify_user()
        except Exception as e:
            print(e)
            notify_user(text="商品抢购失败")
        finally:
            print("20s后关闭浏览器...")
            sleep(20)
            self.driver.quit()

    def get_cookie(self):
        """
        将浏览器cookie存入文件
        :return:
        """
        # 获取浏览器cookies(dict类型)
        cookies = self.driver.get_cookies()
        # 将cookie转换为json字符串,并写入文件
        cookie_json = json.dumps(cookies)
        with open('./tb_cookies.txt', 'w', encoding='utf-8') as f:
            f.write(cookie_json)

说明

这段代码是一个Python脚本,使用了Selenium库来模拟在网页上的用户操作,目的是自动完成淘宝的抢购过程。这个过程包括登录、等待抢购时间、选购商品、结算、提交订单以及支付。以下是对这个脚本关键部分的逐步分析:

类结构和初始化

– `TaoBao`类初始化时,需要指定Chrome驱动的路径、抢购时间和支付密码。

– `chrome_path`用于指定ChromeDriver的路径,`seckill_time`为抢购时间,`password`为支付密码。

方法解析

– `start_driver()`: 初始化和启动Selenium WebDriver。如果在系统默认路径下找不到ChromeDriver,则会尝试从`chrome_path`指定的路径加载。

– `find_chromedriver()`: 尝试在系统默认路径和提供的`chrome_path`中寻找并启动ChromeDriver。

– `login()`: 打开淘宝主页,尝试通过扫码登录。这个方法会等待一段时间,允许用户扫码登录。如果登录成功,则跳转到购物车页面。

– `keep_wait()`: 在抢购时间之前,该方法会持续刷新页面,防止登录超时。当接近抢购时间时,停止刷新,准备抢购。

– `sec_kill()`: 抢购的主要逻辑。在设定的抢购时间点到达时,尝试全选购物车中的商品并进行结算和提交订单。

– `pay()`: 如果提交订单成功,该方法会尝试自动填写支付密码并完成支付。

– `get_cookie()`: 获取当前会话的cookie并保存到文件中,这可能用于后续的会话恢复或分析。

抢购流程

1. 登录: 使用扫码登录淘宝。

2. 等待抢购时间: 在抢购时间到来之前,定期刷新页面以维持会话状态。

3. 执行抢购: 在设定的抢购时间,自动选择购物车中的所有商品,点击结算并提交订单。

4. 支付: 在订单提交后,自动填写支付密码并尝试支付。

异常处理

– 代码中包含了多处异常处理,以应对在登录、选择商品、结算和支付过程中可能出现的问题。

main.py 代码如下

from datetime import datetime
from tkinter import *
from tkinter.ttk import Combobox

from seckill.taobao import TaoBao



def run_killer(time, password, platform):
    # 抢购时间
    seckill_time = time.get()
    # 支付密码
    password = str(password.get())
    # 平台类型
    platform = platform.get()
    # print(seckill_time, password)
    if platform == "淘宝":
        TaoBao(seckill_time_str=seckill_time, password=password).sec_kill(login_time_out=15)
    else:
        raise Exception("未知平台类型")


def main():
    win = Tk()
    win.title('电商秒杀助手')
    win.iconbitmap("img/icon.ico")
    width = 540
    height = 350
    screenwidth = win.winfo_screenwidth()
    screenheight = win.winfo_screenheight()
    align_str = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
    win.geometry(align_str)

    # 设置开抢时间
    label1 = Label(win, text="开抢时间:", width=12, height=3, font=("Lucida Grande", 12))
    label1.grid(column=0, row=0)
    start_time = StringVar()
    time = Entry(win, textvariable=start_time, width=23, fg="blue", font=("Lucida Grande", 12))
    time.grid(column=1, row=0)
    start_time.set(str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")))

    # 支付密码
    label2 = Label(win, text="支付密码:", width=12, height=2, font=("Lucida Grande", 12))
    label2.grid(column=0, row=1)
    password = Entry(win, width=23, show='*', fg="blue", font=("Lucida Grande", 12))
    password.grid(column=1, row=1)

    # 选择平台
    label3 = Label(win, text="抢购平台:", width=12, height=3, font=("Lucida Grande", 12))
    label3.grid(column=0, row=2)
    platform_value = StringVar()
    platform = Combobox(win, textvariable=platform_value, width=18, font=("Lucida Grande", 13))
    platform["values"] = ("淘宝")
    # 默认选择第一个
    platform.current(0)
    platform.grid(column=1, row=2)

    # 开始抢购
    b1 = Button(win, text='开始抢购',
                command=lambda: run_killer(time, password, platform),
                background="green", width=21, height=6,
                font=("Lucida Grande", 13))
    b1.place(x=320, y=16)
    win.resizable(width=False, height=False)

    # 使用说明
    txt0 = Label(win, text='使用说明:', width=10, height=1, font=("Lucida Grande", 11), fg='green')
    txt0.place(x=10, y=150)

    txt1 = Label(win, text='1、安装chrome浏览器以及chromeDriver(放置在python安装根目录下)',
                 font=("Lucida Grande", 10),
                 fg='green')
    txt1.place(x=15, y=180)

    txt2 = Label(win, text='2、抢购前要清空购物车,然后把要抢的东西加入购物车',
                 font=("Lucida Grande", 10),
                 fg='green')
    txt2.place(x=15, y=205)

    txt3 = Label(win, text='3、开抢时间必须是 %Y-%m-%d %H:%M:%S 形式,如2020-12-29 12:10:15',
                 font=("Lucida Grande", 10),
                 fg='green')
    txt3.place(x=15, y=230)

    txt4 = Label(win, text='4、输入开抢时间和支付密码后点开始,程序会控制浏览器打开淘宝登陆页',
                 font=("Lucida Grande", 10),
                 fg='green')
    txt4.place(x=15, y=255)

    txt5 = Label(win, text='5、扫码登陆后,程序会自动刷新购物车页面,到点会完成抢购动作',
                 font=("Lucida Grande", 10),
                 fg='green')
    txt5.place(x=15, y=280)

    txt6 = Label(win, text='6、如果想手动付款,输入开抢时间后不用输入支付密码,直接点开始就可以了',
                 font=("Lucida Grande", 10),
                 fg='green')
    txt6.place(x=15, y=305)
    win.mainloop()


if __name__ == '__main__':
    main()

说明

这段代码实现了一个基于Tkinter GUI的电商秒杀助手应用,用于自动化处理京东和淘宝的商品抢购过程。用户可以通过这个界面设置抢购时间、支付密码,并选择抢购平台(淘宝)。下面是对这段代码的具体分析:

主要功能

1. GUI设置:使用Tkinter创建图形用户界面,包括输入框、下拉框和按钮,允许用户输入抢购的详细信息。

2. 抢购时间和支付密码输入:用户可以输入具体的抢购时间和支付密码。

3. 平台选择:用户可以通过下拉菜单选择要抢购的电商平台,目前支持淘宝和其他。

4. 开始抢购按钮:点击后根据输入的时间、密码和选择的平台执行抢购操作。

代码结构解析

– run_killer() 函数:根据用户在GUI中设置的时间、密码和平台,实例化相应的京东或淘宝秒杀类,并调用其`sec_kill()`方法开始抢购。

– main() 函数:设置GUI窗口,包括所有的标签、输入框、按钮和文本说明。此外,还设定了窗口的大小和位置。

GUI 组件

– 时间输入:使用`Entry`组件让用户输入抢购的具体时间。

– 密码输入:使用`Entry`组件让用户输入支付密码,输入显示为星号(*)以保密。

– 平台选择:使用`Combobox`组件让用户选择抢购平台。

– 开始按钮:使用`Button`组件,用户点击后调用`run_killer()`函数。

使用说明

界面下方提供了详细的使用说明,指导用户如何使用这个工具,包括如何设置时间、清空购物车、扫码登录等步骤。

代码运行流程

1. 运行程序后,显示主窗口。

2. 用户输入抢购时间、支付密码(可选)。

3. 选择抢购平台。

4. 点击开始抢购,程序会在后台根据设定的时间自动打开浏览器,登录并执行抢购动作。

注意事项

 

 

© 版权声明
THE END
喜欢就支持一下吧
点赞29 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容