├── img ├── icon.ico ├── tools.png ├── chrome.png └── webdrive.png ├── seckill ├── __pycache__ │ ├── jd.cpython-39.pyc │ └── taobao.cpython-39.pyc ├── taobao.py └── jd.py ├── utils ├── __pycache__ │ └── utils.cpython-39.pyc ├── utils.py └── useragents.txt ├── .gitignore ├── README.md └── main.py /img/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rosons/seckill_tools/HEAD/img/icon.ico -------------------------------------------------------------------------------- /img/tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rosons/seckill_tools/HEAD/img/tools.png -------------------------------------------------------------------------------- /img/chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rosons/seckill_tools/HEAD/img/chrome.png -------------------------------------------------------------------------------- /img/webdrive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rosons/seckill_tools/HEAD/img/webdrive.png -------------------------------------------------------------------------------- /seckill/__pycache__/jd.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rosons/seckill_tools/HEAD/seckill/__pycache__/jd.cpython-39.pyc -------------------------------------------------------------------------------- /utils/__pycache__/utils.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rosons/seckill_tools/HEAD/utils/__pycache__/utils.cpython-39.pyc -------------------------------------------------------------------------------- /seckill/__pycache__/taobao.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rosons/seckill_tools/HEAD/seckill/__pycache__/taobao.cpython-39.pyc -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### IntelliJ IDEA ### 2 | .mvn 3 | .jar 4 | .idea 5 | *.iws 6 | *.iml 7 | *.ipr 8 | 9 | ### NetBeans ### 10 | /nbproject/private/ 11 | /nbbuild/ 12 | /dist/ 13 | /nbdist/ 14 | /.nb-gradle/ 15 | build/ 16 | 17 | ### VS Code ### 18 | .vscode/ 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # seckill_tools 2 | 同时支持多种电商平台的商品秒杀(抢购)活动,如**淘宝、天猫、京东**商品秒杀等。 3 | 4 | > 本项目是在作者 `jerry3747` 的仓库代码基础之上,进行了优化。 5 | > 6 | > 主要有: 7 | > 8 | > ​ 1、优化了**秒杀代码的逻辑**,进行了**代码注释**,并优化了**脚本工具界面的外观**,可用性增强。 9 | > 10 | > ​ 2、功能增强,**新增了对京东平台的商品秒杀功能。** 11 | > 12 | > 如需要访问原仓库,移步 https://github.com/jerry3747/taobao_seckill 13 | 14 | ![](img/tools.png) 15 | 16 | ## 工具依赖 17 | #### 需要安装chrome浏览器,并且根据浏览器的版本找到对应的chromedriver浏览器驱动,chrome浏览器版本在114之前的,可通过 http://chromedriver.storage.googleapis.com/index.html 地址进行下载,chrome浏览器版本在115以上的,可通过 https://storage.googleapis.com/chrome-for-testing-public/{chrome浏览器版本号}/win32/chromedriver-win32.zip 进行下载,然后将chromedriver浏览器驱动解压到python安装的根目录下即可。 18 | 19 | ![](img/chrome.png) 20 | 21 | ![](img/webdrive.png) 22 | 23 | ## Web版使用说明 24 | 25 | 1. 抢购前请校准本地电脑的时间,再将需要抢购的商品加入到购物车(为防止出现未知错误,尽量将不需要抢购的商品清除) 26 | 2. (可选) 如果要打包成可执行文件,可使用 `pyinstaller` 自行打包 27 | 3. 不需要打包的,直接在项目根目录下,执行 python3 main.py 28 | 4. (可选) 消息推送提醒(如微信/钉钉群机器人/邮箱等),在 https://courier.toptopn.com/ 上免费注册账户,得到账户 `UUID` ,按照此网站的接口文档,在 `utils/utils.py` 中修改 `notify_user()` 中的参数即可。再执行 `python3 main.py` 29 | 5. 程序运行后,输入抢购时间、支付密码、选择平台,点击抢购,则会自动打开淘宝/京东登陆页,需要自己手动点击切换到扫码登陆,扫码登录成功后,即可自动抢购。 30 | -------------------------------------------------------------------------------- /utils/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | from random import choice 3 | 4 | import requests 5 | from selenium import webdriver 6 | 7 | 8 | # 获取useragent信息 9 | def get_useragent_data(filename: str = "./useragents.txt") -> list: 10 | root_folder = os.path.dirname(__file__) 11 | user_agents_file = os.path.join(root_folder, filename) 12 | try: 13 | with open(user_agents_file, 'r', encoding='utf-8') as reader: 14 | data = [_.strip() for _ in reader.readlines()] 15 | except Exception as e: 16 | print(e) 17 | data = ["Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"] 18 | return data 19 | 20 | 21 | # 配置chrome启动项 22 | def build_chrome_options(): 23 | """配置启动项""" 24 | chrome_options = webdriver.ChromeOptions() 25 | chrome_options.accept_untrusted_certs = True 26 | chrome_options.assume_untrusted_cert_issuer = True 27 | arguments = ['--no-sandbox', '--disable-impl-side-painting', '--disable-setuid-sandbox', 28 | '--disable-seccomp-filter-sandbox', 29 | '--disable-breakpad', '--disable-client-side-phishing-detection', '--disable-cast', 30 | '--disable-cast-streaming-hw-encoding', '--disable-cloud-import', '--disable-popup-blocking', 31 | '--ignore-certificate-errors', '--disable-session-crashed-bubble', '--disable-ipv6', 32 | '--allow-http-screen-capture', '--start-maximized', '--ignore-ssl-errors'] 33 | for arg in arguments: 34 | chrome_options.add_argument(arg) 35 | chrome_options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging']) 36 | chrome_options.add_argument(f'--user-agent={choice(get_useragent_data())}') 37 | return chrome_options 38 | 39 | 40 | # 消息推送 41 | def notify_user(uuid="5d4bc588e000bfc", 42 | title="秒杀通知", 43 | text="商品抢购成功!", 44 | html=None, 45 | uids="UID_orEZQ6c54qCO3KzMkQT5CdzcWU7g_N", 46 | emails=""): 47 | """ 48 | 推送消息 49 | :param uuid: 账户ID 50 | :param title: 消息标题 51 | :param text: 消息内容 52 | :param html: 消息详情(支持html格式) 53 | :param uids: 推送到的微信UID,多个UID用英文逗号,分割 54 | :param emails: 推送到的邮箱地址,多个邮箱地址用英文逗号,分割 55 | :return: 56 | """ 57 | # 调用接口完成信息的推送 58 | res = requests.post(url="https://courier.toptopn.com/api/v1/cui/notify/push", json=dict( 59 | uuid=uuid, 60 | uids=uids, 61 | title=title, 62 | text=text, 63 | html=html, 64 | emails=emails 65 | )).json() 66 | print("消息推送结果:{}".format(res)) 67 | 68 | 69 | if __name__ == '__main__': 70 | notify_user() 71 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from tkinter import * 3 | from tkinter.ttk import Combobox 4 | 5 | from seckill.taobao import TaoBao 6 | from seckill.jd import JDong 7 | 8 | 9 | def run_killer(time, password, platform): 10 | # 抢购时间 11 | seckill_time = time.get() 12 | # 支付密码 13 | password = str(password.get()) 14 | # 平台类型 15 | platform = platform.get() 16 | # print(seckill_time, password) 17 | if platform == "京东": 18 | JDong(seckill_time_str=seckill_time, password=password).sec_kill(login_time_out=15) 19 | elif platform == "淘宝": 20 | TaoBao(seckill_time_str=seckill_time, password=password).sec_kill(login_time_out=15) 21 | else: 22 | raise Exception("未知平台类型") 23 | 24 | 25 | def main(): 26 | win = Tk() 27 | win.title('电商秒杀助手') 28 | win.iconbitmap("img/icon.ico") 29 | width = 540 30 | height = 350 31 | screenwidth = win.winfo_screenwidth() 32 | screenheight = win.winfo_screenheight() 33 | align_str = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) 34 | win.geometry(align_str) 35 | 36 | # 设置开抢时间 37 | label1 = Label(win, text="开抢时间:", width=12, height=3, font=("Lucida Grande", 12)) 38 | label1.grid(column=0, row=0) 39 | start_time = StringVar() 40 | time = Entry(win, textvariable=start_time, width=23, fg="blue", font=("Lucida Grande", 12)) 41 | time.grid(column=1, row=0) 42 | start_time.set(str(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) 43 | 44 | # 支付密码 45 | label2 = Label(win, text="支付密码:", width=12, height=2, font=("Lucida Grande", 12)) 46 | label2.grid(column=0, row=1) 47 | password = Entry(win, width=23, show='*', fg="blue", font=("Lucida Grande", 12)) 48 | password.grid(column=1, row=1) 49 | 50 | # 选择平台 51 | label3 = Label(win, text="抢购平台:", width=12, height=3, font=("Lucida Grande", 12)) 52 | label3.grid(column=0, row=2) 53 | platform_value = StringVar() 54 | platform = Combobox(win, textvariable=platform_value, width=18, font=("Lucida Grande", 13)) 55 | platform["values"] = ("京东", "淘宝") 56 | # 默认选择第一个 57 | platform.current(0) 58 | platform.grid(column=1, row=2) 59 | 60 | # 开始抢购 61 | b1 = Button(win, text='开始抢购', 62 | command=lambda: run_killer(time, password, platform), 63 | background="green", width=21, height=6, 64 | font=("Lucida Grande", 13)) 65 | b1.place(x=320, y=16) 66 | win.resizable(width=False, height=False) 67 | 68 | # 使用说明 69 | txt0 = Label(win, text='使用说明:', width=10, height=1, font=("Lucida Grande", 11), fg='green') 70 | txt0.place(x=10, y=150) 71 | 72 | txt1 = Label(win, text='1、安装chrome浏览器以及chromeDriver(放置在python安装根目录下)', 73 | font=("Lucida Grande", 10), 74 | fg='green') 75 | txt1.place(x=15, y=180) 76 | 77 | txt2 = Label(win, text='2、抢购前要清空购物车,然后把要抢的东西加入购物车', 78 | font=("Lucida Grande", 10), 79 | fg='green') 80 | txt2.place(x=15, y=205) 81 | 82 | txt3 = Label(win, text='3、开抢时间必须是 %Y-%m-%d %H:%M:%S 形式,如2020-12-29 12:10:15', 83 | font=("Lucida Grande", 10), 84 | fg='green') 85 | txt3.place(x=15, y=230) 86 | 87 | txt4 = Label(win, text='4、输入开抢时间和支付密码后点开始,程序会控制浏览器打开淘宝登陆页', 88 | font=("Lucida Grande", 10), 89 | fg='green') 90 | txt4.place(x=15, y=255) 91 | 92 | txt5 = Label(win, text='5、扫码登陆后,程序会自动刷新购物车页面,到点会完成抢购动作', 93 | font=("Lucida Grande", 10), 94 | fg='green') 95 | txt5.place(x=15, y=280) 96 | 97 | txt6 = Label(win, text='6、如果想手动付款,输入开抢时间后不用输入支付密码,直接点开始就可以了', 98 | font=("Lucida Grande", 10), 99 | fg='green') 100 | txt6.place(x=15, y=305) 101 | win.mainloop() 102 | 103 | 104 | if __name__ == '__main__': 105 | main() 106 | -------------------------------------------------------------------------------- /seckill/taobao.py: -------------------------------------------------------------------------------- 1 | import json 2 | from time import sleep 3 | from datetime import datetime 4 | 5 | from selenium import webdriver 6 | from selenium.common.exceptions import WebDriverException 7 | from selenium.webdriver.common.by import By 8 | from selenium.webdriver.support.ui import WebDriverWait 9 | from selenium.webdriver.support import expected_conditions as EC 10 | 11 | from utils.utils import notify_user 12 | from utils.utils import build_chrome_options 13 | 14 | # 抢购失败最大次数 15 | max_retry_count = 30 16 | 17 | 18 | # 自动抢票类(淘宝) 19 | class TaoBao: 20 | 21 | def __init__(self, chrome_path="./chromedriver.exe", seckill_time_str=None, password=None): 22 | # 驱动路径 23 | self.chrome_path = chrome_path 24 | # 抢购时间 25 | self.seckill_time = datetime.strptime(seckill_time_str, '%Y-%m-%d %H:%M:%S') 26 | # 支付密码 27 | self.password = password 28 | # chrome驱动 29 | self.driver = None 30 | 31 | # 获取chrome驱动 32 | def start_driver(self): 33 | try: 34 | driver = self.find_chromedriver() 35 | except WebDriverException: 36 | print("Unable to find chromedriver, Please check the drive path.") 37 | else: 38 | return driver 39 | 40 | # 寻找chrome驱动(首先去python安装目录下找,其次再去传入的路径找) 41 | def find_chromedriver(self): 42 | try: 43 | driver = webdriver.Chrome() 44 | except WebDriverException: 45 | try: 46 | driver = webdriver.Chrome(executable_path=self.chrome_path, chrome_options=build_chrome_options()) 47 | except WebDriverException: 48 | raise Exception("Unable to find chromedriver, Please check the drive path.") 49 | return driver 50 | 51 | # 登录淘宝 52 | def login(self, login_url="https://www.taobao.com", login_time_out=10): 53 | if login_url: 54 | self.driver = self.start_driver() 55 | else: 56 | raise Exception("Please input the login url.") 57 | while True: 58 | # 打开首页 59 | self.driver.get(login_url) 60 | try: 61 | # 尝试获取点击登录超链接 62 | a_lists = self.driver.find_elements(By.XPATH, '//div[@class="site-nav-sign"]/a') 63 | # 获取到了,说明还未登录,进行登录 64 | if len(a_lists) > 0: 65 | print("没登录,开始点击登录按钮...") 66 | # 亲,请登录 67 | login_button = a_lists[0] 68 | login_button.click() 69 | print("请在{}s内扫码登陆!!".format(login_time_out)) 70 | # 睡眠login_time_out(s) 71 | sleep(login_time_out) 72 | # 尝试获取登录成功页面的元素,找到了表示已经登录成功。 73 | if self.driver.find_element(By.XPATH, '//*[@id="J_SiteNavMytaobao"]/div[1]/a/span'): 74 | print("登陆成功") 75 | # 进入购物车 76 | self.driver.get("https://cart.taobao.com/cart.htm") 77 | # 结束循环 78 | break 79 | else: 80 | print("登陆失败, 刷新重试, 请尽快登陆!!!") 81 | continue 82 | except Exception as e: 83 | print(str(e)) 84 | continue 85 | 86 | # 等待抢购 87 | def keep_wait(self): 88 | print("等待到点抢购...") 89 | while True: 90 | # 获取当前时间 91 | current_time = datetime.now() 92 | # 如果距离抢购时间大于3分钟,则每分钟刷新一次界面,防止登录超时。 93 | if (self.seckill_time - current_time).seconds > 180: 94 | # 进入购物车 95 | self.driver.get("https://cart.taobao.com/cart.htm") 96 | print("每分钟刷新一次界面,防止登录超时...") 97 | sleep(60) 98 | else: 99 | # 调用函数,将浏览器cookie写入文件备用。 100 | self.get_cookie() 101 | print("抢购时间点将近,停止自动刷新,准备进入抢购阶段...") 102 | # 抢购时间将近,结束等待抢购 103 | break 104 | 105 | # 抢购的入口函数 106 | def sec_kill(self, login_time_out=15): 107 | print("此次抢购时间:{}".format(datetime.strftime(self.seckill_time, "%Y-%m-%d %H:%M:%S"))) 108 | # 调用登录函数 109 | self.login(login_time_out=login_time_out) 110 | # 调用等待抢购函数 111 | self.keep_wait() 112 | 113 | # 获取全选框 114 | select_all = self.driver.find_element(By.ID, "J_SelectAll1") 115 | if select_all: 116 | print("当前未选状态,自动选择全部商品") 117 | # 点击全选 118 | select_all.click() 119 | print("已经选中全部商品!!!") 120 | 121 | # 记录提交状态 122 | submit_success = False 123 | # 重试抢购次数 124 | retry_count = 0 125 | 126 | while True: 127 | # 获取当前时间 128 | now = datetime.now() 129 | if now >= self.seckill_time: 130 | print(f"开始抢购, 尝试次数: {str(retry_count + 1)}") 131 | else: 132 | # 睡眠一段时间,防止cpu一直工作 133 | sleep(0.1) 134 | continue 135 | try: 136 | # 等待结算按钮可以被点击 137 | button = WebDriverWait(self.driver, 5, poll_frequency=0.1).until( 138 | EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_SmallSubmit'))) 139 | # 点击结算 140 | button.click() 141 | print("已经点击结算按钮...") 142 | # 等待跳转到提交订单按钮可以被点击 143 | submit = WebDriverWait(self.driver, 5, poll_frequency=0.1).until( 144 | EC.element_to_be_clickable((By.CSS_SELECTOR, '#submitOrderPC_1 > div > a.go-btn'))) 145 | # 点击提交订单 146 | submit.click() 147 | print("已经点击提交订单按钮...") 148 | # 记录提交状态 149 | submit_success = True 150 | # 退出循环 151 | break 152 | except Exception as e: 153 | print(e) 154 | print("临时写的脚本, 可能出了点问题!!!") 155 | retry_count += 1 156 | if retry_count > max_retry_count: 157 | print("重试抢购次数达到上限,放弃重试...") 158 | break 159 | # 提交成功,准备支付 160 | if submit_success: 161 | if self.password: 162 | self.pay() 163 | 164 | def pay(self): 165 | try: 166 | # 等待密码框加载完毕 167 | element = WebDriverWait(self.driver, 5).until( 168 | EC.presence_of_element_located((By.CLASS_NAME, 'sixDigitPassword'))) 169 | # 输入密码 170 | element.send_keys(self.password) 171 | print("密码输入完成") 172 | # 等待确认付款按钮加载完成,并付款 173 | WebDriverWait(self.driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#J_authSubmit'))).click() 174 | print("付款成功") 175 | notify_user() 176 | except Exception as e: 177 | print(e) 178 | notify_user(text="商品抢购失败") 179 | finally: 180 | print("20s后关闭浏览器...") 181 | sleep(20) 182 | self.driver.quit() 183 | 184 | def get_cookie(self): 185 | """ 186 | 将浏览器cookie存入文件 187 | :return: 188 | """ 189 | # 获取浏览器cookies(dict类型) 190 | cookies = self.driver.get_cookies() 191 | # 将cookie转换为json字符串,并写入文件 192 | cookie_json = json.dumps(cookies) 193 | with open('./tb_cookies.txt', 'w', encoding='utf-8') as f: 194 | f.write(cookie_json) 195 | -------------------------------------------------------------------------------- /seckill/jd.py: -------------------------------------------------------------------------------- 1 | import json 2 | from time import sleep 3 | from datetime import datetime 4 | 5 | from selenium import webdriver 6 | from selenium.common.exceptions import WebDriverException 7 | from selenium.webdriver.common.by import By 8 | from selenium.webdriver.support.ui import WebDriverWait 9 | from selenium.webdriver.support import expected_conditions as EC 10 | 11 | from utils.utils import notify_user 12 | from utils.utils import build_chrome_options 13 | 14 | # 抢购失败最大次数 15 | max_retry_count = 30 16 | 17 | 18 | # 自动抢票类(京东) 19 | class JDong: 20 | 21 | def __init__(self, chrome_path="./chromedriver.exe", seckill_time_str=None, password=None): 22 | # 驱动路径 23 | self.chrome_path = chrome_path 24 | # 抢购时间 25 | self.seckill_time = datetime.strptime(seckill_time_str, '%Y-%m-%d %H:%M:%S') 26 | # 支付密码 27 | self.password = password 28 | # chrome驱动 29 | self.driver = None 30 | 31 | # 获取chrome驱动 32 | def start_driver(self): 33 | try: 34 | driver = self.find_chromedriver() 35 | except WebDriverException: 36 | print("Unable to find chromedriver, Please check the drive path.") 37 | else: 38 | return driver 39 | 40 | # 寻找chrome驱动(首先去python安装目录下找,其次再去传入的路径找) 41 | def find_chromedriver(self): 42 | try: 43 | driver = webdriver.Chrome() 44 | except WebDriverException: 45 | try: 46 | driver = webdriver.Chrome(executable_path=self.chrome_path, chrome_options=build_chrome_options()) 47 | except WebDriverException: 48 | raise Exception("Unable to find chromedriver, Please check the drive path.") 49 | return driver 50 | 51 | # 登录京东 52 | def login(self, login_url="https://jd.com", login_time_out=10): 53 | if login_url: 54 | self.driver = self.start_driver() 55 | else: 56 | raise Exception("Please input the login url.") 57 | while True: 58 | # 打开首页 59 | self.driver.get(login_url) 60 | try: 61 | # 尝试获取点击登录超链接 62 | a_lists = self.driver.find_elements(By.XPATH, '//a[@class="link-login"]') 63 | # 获取到了,说明还未登录,进行登录 64 | if len(a_lists) > 0: 65 | print("没登录,开始点击登录按钮...") 66 | # 您好,请登录 67 | a_login = a_lists[0] 68 | a_login.click() 69 | print("请在{}s内扫码登陆!!".format(login_time_out)) 70 | # 睡眠login_time_out(s) 71 | sleep(login_time_out) 72 | # 尝试获取点击登录超链接,未找到则表示已经登录成功。 73 | if len(self.driver.find_elements(By.XPATH, '//a[@class="link-login"]')) == 0: 74 | print("登陆成功") 75 | # 进入购物车 76 | self.driver.get("https://cart.jd.com/cart_index") 77 | # 结束循环 78 | break 79 | else: 80 | print("登陆失败, 刷新重试, 请尽快登陆!!!") 81 | continue 82 | except Exception as e: 83 | print(str(e)) 84 | continue 85 | 86 | # 等待抢购 87 | def keep_wait(self): 88 | print("等待到点抢购...") 89 | while True: 90 | # 获取当前时间 91 | current_time = datetime.now() 92 | # 如果距离抢购时间大于3分钟,则每分钟刷新一次界面,防止登录超时。 93 | if (self.seckill_time - current_time).seconds > 180: 94 | # 进入购物车 95 | self.driver.get("https://cart.jd.com/cart_index") 96 | print("每分钟刷新一次界面,防止登录超时...") 97 | sleep(60) 98 | else: 99 | # 调用函数,将浏览器cookie写入文件备用。 100 | self.get_cookie() 101 | print("抢购时间点将近,停止自动刷新,准备进入抢购阶段...") 102 | # 抢购时间将近,结束等待抢购 103 | break 104 | 105 | # 抢购的入口函数 106 | def sec_kill(self, login_time_out=15): 107 | print("此次抢购时间:{}".format(datetime.strftime(self.seckill_time, "%Y-%m-%d %H:%M:%S"))) 108 | # 调用登录函数 109 | self.login(login_time_out=login_time_out) 110 | # 调用等待抢购函数 111 | self.keep_wait() 112 | 113 | # 获取全选框 114 | select_all = self.driver.find_element(By.XPATH, 115 | '//div[@class="column t-checkbox"]//input[@class="jdcheckbox"]') 116 | if select_all: 117 | # 获取全选框的值(如果已选中,则返回true,否则返回None) 118 | # 因为京东会记录上一次选中的情况,所以需要判断是否选中,如果未选中,才去自动选中。 119 | is_check_all = select_all.get_attribute('checked') 120 | # print(is_check_all) 121 | if not is_check_all: 122 | print("当前未选状态,自动选择全部商品") 123 | # 点击全选 124 | select_all.click() 125 | print("已经选中全部商品!!!") 126 | 127 | # 记录提交状态 128 | submit_success = False 129 | # 重试抢购次数 130 | retry_count = 0 131 | 132 | while True: 133 | # 获取当前时间 134 | now = datetime.now() 135 | if now >= self.seckill_time: 136 | # 正式抢购时,再次检查是否选中了商品 137 | # 因为京东秒杀时间之前,是不能够选择商品的,所以在正式抢购时,需要再次判断是否选中 138 | if select_all: 139 | is_check_all = select_all.get_attribute('checked') 140 | # print(is_check_all) 141 | if not is_check_all: 142 | print("当前状态仍未选择,再次选择全部商品") 143 | # 点击全选 144 | select_all.click() 145 | else: 146 | print("已核实当前处于选中状态") 147 | print(f"开始抢购, 尝试次数: {str(retry_count + 1)}") 148 | else: 149 | # 睡眠一段时间,防止cpu一直工作 150 | sleep(0.1) 151 | continue 152 | try: 153 | # 等待结算按钮可以被点击 154 | button = WebDriverWait(self.driver, 5, poll_frequency=0.1).until( 155 | EC.element_to_be_clickable((By.CSS_SELECTOR, '.common-submit-btn'))) 156 | # 点击结算 157 | button.click() 158 | print("已经点击结算按钮...") 159 | # 等待跳转到提交订单按钮可以被点击 160 | submit = WebDriverWait(self.driver, 5, poll_frequency=0.1).until( 161 | EC.element_to_be_clickable((By.CSS_SELECTOR, '.checkout-submit'))) 162 | # 点击提交订单 163 | submit.click() 164 | print("已经点击提交订单按钮...") 165 | # 等待跳转到立即支付按钮可以被点击 166 | pay = WebDriverWait(self.driver, 5, poll_frequency=0.1).until( 167 | EC.element_to_be_clickable((By.XPATH, '//div[@class="pay-button-wrapper"]//div[@class="base-button pointer-g"]'))) 168 | # 点击立即支付 169 | pay.click() 170 | print("已经点击立即支付按钮...") 171 | # 记录提交状态 172 | submit_success = True 173 | # 退出循环 174 | break 175 | except Exception as e: 176 | print(e) 177 | print("临时写的脚本, 可能出了点问题!!!") 178 | retry_count += 1 179 | if retry_count > max_retry_count: 180 | print("重试抢购次数达到上限,放弃重试...") 181 | break 182 | # 提交成功,准备支付 183 | if submit_success: 184 | if self.password: 185 | self.pay() 186 | 187 | def pay(self): 188 | try: 189 | # 等待弹窗内的密码框加载完毕 190 | element = WebDriverWait(self.driver, 5).until( 191 | EC.presence_of_element_located((By.ID, 'shortPwdInput'))) 192 | # 输入密码 193 | element.send_keys(self.password) 194 | print("密码输入完成") 195 | # 等待弹窗的立即支付按钮加载完成,并付款 196 | WebDriverWait(self.driver, 5).until( 197 | EC.presence_of_element_located((By.XPATH, '//div[@class="btn"]//div[@class="base-button pointer-g"]')))\ 198 | .click() 199 | print("付款成功") 200 | notify_user() 201 | except Exception as e: 202 | print(e) 203 | notify_user(text="商品抢购失败") 204 | finally: 205 | print("20s后关闭浏览器...") 206 | sleep(20) 207 | self.driver.quit() 208 | 209 | def get_cookie(self): 210 | """ 211 | 将浏览器cookie存入文件 212 | :return: 213 | """ 214 | # 获取浏览器cookies(dict类型) 215 | cookies = self.driver.get_cookies() 216 | # 将cookie转换为json字符串,并写入文件 217 | cookie_json = json.dumps(cookies) 218 | with open('./jd_cookies.txt', 'w', encoding='utf-8') as f: 219 | f.write(cookie_json) 220 | -------------------------------------------------------------------------------- /utils/useragents.txt: -------------------------------------------------------------------------------- 1 | Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0) 2 | Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0) 3 | Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0) 4 | Mozilla/4.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0) 5 | Mozilla/1.22 (compatible; MSIE 10.0; Windows 3.1) 6 | Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US)) 7 | Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US) 8 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0) 9 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7) 10 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7 11 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 4.0; InfoPath.3; MS-RTC LM 8; .NET4.0C; .NET4.0E) 12 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0) 13 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0) 14 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 4.0; Tablet PC 2.0; InfoPath.3; .NET4.0C; .NET4.0E) 15 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0 16 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; chromeframe/11.0.696.57) 17 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205 18 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; chromeframe/11.0.696.57) 19 | Mozilla/5.0 ( ; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0) 20 | Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0) 21 | Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 7.1; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C) 22 | Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; AskTB5.5) 23 | Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.2; .NET4.0C; .NET4.0E) 24 | Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C) 25 | Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; FDM; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; Tablet PC 2.0) 26 | Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320) 27 | Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322) 28 | Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 29 | Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727) 30 | Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.0; Trident/4.0; InfoPath.1; SV1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 3.0.04506.30) 31 | Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.0; Trident/4.0; FBSMTWB; .NET CLR 2.0.34861; .NET CLR 3.0.3746.3218; .NET CLR 3.5.33652; msn OptimizedIE8;ENUS) 32 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0) 33 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8) 34 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8 35 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; Media Center PC 6.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C) 36 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.3; .NET4.0C; .NET4.0E; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8) 37 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2) 38 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 3.0) 39 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; msn OptimizedIE8;ZHCN) 40 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; InfoPath.3; .NET4.0C; .NET4.0E) chromeframe/8.0.552.224 41 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; .NET4.0C; .NET4.0E; Zune 4.7; InfoPath.3) 42 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; .NET4.0C; .NET4.0E; Zune 4.7) 43 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8) 44 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; Zune 4.0) 45 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MS-RTC LM 8; Zune 4.7) 46 | Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre 47 | Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20100101 Firefox/4.2a1pre 48 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre 49 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.2a1pre) Gecko/20110323 Firefox/4.2a1pre 50 | Mozilla/5.0 (X11; Linux x86_64; rv:2.0b9pre) Gecko/20110111 Firefox/4.0b9pre 51 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b9pre) Gecko/20101228 Firefox/4.0b9pre 52 | Mozilla/5.0 (Windows NT 5.1; rv:2.0b9pre) Gecko/20110105 Firefox/4.0b9pre 53 | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b8pre) Gecko/20101114 Firefox/4.0b8pre 54 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101213 Firefox/4.0b8pre 55 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101128 Firefox/4.0b8pre 56 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101114 Firefox/4.0b8pre 57 | Mozilla/5.0 (Windows NT 5.1; rv:2.0b8pre) Gecko/20101127 Firefox/4.0b8pre 58 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b8) Gecko/20100101 Firefox/4.0b8 59 | Mozilla/5.0 (Windows NT 6.1; rv:2.0b7pre) Gecko/20100921 Firefox/4.0b7pre 60 | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b7) Gecko/20101111 Firefox/4.0b7 61 | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b7) Gecko/20100101 Firefox/4.0b7 62 | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre 63 | Mozilla/5.0 (Windows NT 6.1; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre Firefox/4.0b6pre 64 | Mozilla/5.0 (X11; Linux x86_64; rv:2.0b4) Gecko/20100818 Firefox/4.0b4 65 | Mozilla/5.0 (X11; Linux i686; rv:2.0b3pre) Gecko/20100731 Firefox/4.0b3pre 66 | Mozilla/5.0 (Windows NT 5.2; rv:2.0b13pre) Gecko/20110304 Firefox/4.0b13pre 67 | Mozilla/5.0 (Windows NT 5.1; rv:2.0b13pre) Gecko/20110223 Firefox/4.0b13pre 68 | Mozilla/5.0 (X11; Linux i686; rv:2.0b12pre) Gecko/20110204 Firefox/4.0b12pre 69 | Mozilla/5.0 (X11; Linux i686; rv:2.0b12pre) Gecko/20100101 Firefox/4.0b12pre 70 | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b11pre) Gecko/20110128 Firefox/4.0b11pre 71 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110131 Firefox/4.0b11pre 72 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110129 Firefox/4.0b11pre 73 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110128 Firefox/4.0b11pre 74 | Mozilla/5.0 (Windows NT 6.1; rv:2.0b11pre) Gecko/20110126 Firefox/4.0b11pre 75 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b11pre) Gecko/20110126 Firefox/4.0b11pre 76 | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b10pre) Gecko/20110118 Firefox/4.0b10pre 77 | Mozilla/5.0 (Windows NT 6.1; rv:2.0b10pre) Gecko/20110113 Firefox/4.0b10pre 78 | Mozilla/5.0 (X11; Linux i686; rv:2.0b10) Gecko/20100101 Firefox/4.0b10 79 | Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:2.0b10) Gecko/20110126 Firefox/4.0b10 80 | Mozilla/5.0 (Windows NT 6.1; rv:2.0b10) Gecko/20110126 Firefox/4.0b10 81 | Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:2.0) Gecko/20110307 Firefox/4.0 82 | Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0 83 | Mozilla/5.0 (X11; Arch Linux i686; rv:2.0) Gecko/20110321 Firefox/4.0 84 | Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729) 85 | Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20110319 Firefox/4.0 86 | Mozilla/5.0 (Windows NT 6.1; rv:1.9) Gecko/20100101 Firefox/4.0 87 | Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8 88 | Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8 89 | Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8 90 | Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8 91 | Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.3a5pre) Gecko/20100526 Firefox/3.7a5pre 92 | Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5 93 | Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5 94 | Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5 95 | Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20091218 Firefox 3.6b5 96 | Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2b4) Gecko/20091124 Firefox/3.6b4 (.NET CLR 3.5.30729) 97 | Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2b4) Gecko/20091124 Firefox/3.6b4 98 | Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5 99 | Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2a1pre) Gecko/20090428 Firefox/3.6a1pre 100 | Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2a1pre) Gecko/20090405 Firefox/3.6a1pre 101 | Mozilla/5.0 (X11; U; Linux i686; ru-RU; rv:1.9.2a1pre) Gecko/20090405 Ubuntu/9.04 (jaunty) Firefox/3.6a1pre 102 | Mozilla/5.0 (Windows; Windows NT 5.1; es-ES; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre 103 | Mozilla/5.0 (Windows; Windows NT 5.1; en-US; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre 104 | Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre (.NET CLR 3.5.30729) 105 | Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100915 Gentoo Firefox/3.6.9 106 | Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.2.9) Gecko/20100913 Firefox/3.6.9 107 | Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 ( .NET CLR 3.5.30729; .NET CLR 4.0.20506) 108 | Mozilla/5.0 (Windows; U; Windows NT 5.2; en-GB; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 109 | Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.2.8) Gecko/20101230 Firefox/3.6.8 110 | Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100804 Gentoo Firefox/3.6.8 --------------------------------------------------------------------------------