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. 点击开始抢购,程序会在后台根据设定的时间自动打开浏览器,登录并执行抢购动作。
注意事项
1. 转载请在文内以超链形式注明出处,谢谢合作!
2. 本站除原创内容,其余所有内容均收集自互联网,仅限用于学习和研究目的,本站不对其内容的合法性承担任何责任。如有版权内容,请通知我们或作者删除,其版权均归原作者所有,本站虽力求保存原有版权信息,但因众多资源经多次转载,已无法确定其真实来源,或已将原有信息丢失,所以敬请原作者谅解!
3. 本站用户所发布的一切资源内容不代表本站立场,并不代表本站赞同其观点和对其真实性负责,若您对本站所载资源作品版权归属存有异议,请留言附说明联系邮箱,我们将在第一时间予以处理 ,同时向您表示歉意!为尊重作者版权,请购买原版作品,支持您喜欢的作者,谢谢!
4. 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客如有发现请立即向站长举报;本站资源文件大多存储在云盘,如发现链接或图片失效,请联系作者或站长及时更新。
暂无评论内容