功能特点:
1.不绑定单一品种
2.支持傻瓜式添加目标按钮和输入框
3.支持多步骤(意思就是随便你几步,反正自己爱怎么DIY就怎么DIY)
4.支持目标按钮文本傻瓜式定位(如果不懂css选择器,用这个也可以)
5.CSS选择器+目标文本双重定位,再也不怕错过这个按钮了
这部分仅供python有基础的人看,源码方式打开
支持库安装指令(如果pip都不懂的话那就请自学一下python基础):
pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple/
然后将chromedriver.exe放入python环境中的Scripts文件夹中


20201221更新说明:
1.修复了暂停按钮文字错误的BUG
2.重写了脚本逻辑(现在是安装顺序一个一个判断的,就是必须前面的点成功了才能走到下一步,这样更加节省资源速度更快)
3.增加了输入密码,输入文字的功能(如果造成损失请自负!可以帮忙输入密码或者输入数量,但是请谨慎使用,万一你突然不想买了呢,哈哈)
4.增加定时启动功能(别忘记了要点全部开始,不然到时间也不会启动)
5.增加提前刷新的功能,这个和定时启动搭配使用(有些东西是先预约,到点预约,或者到点后降价等情况,就需要刷新/定时这样就可以匹配上了)
6.增加一件关闭所有浏览器的功能(这样就不需要每次搞错了又要重开软件了)
7.现在所有的修改都会被记录下来,重开软件时会加载你的设置情况
友情提示:
1.datas文件夹下面的set.pkl就是配置信息,这个东西可以在论坛分享,比如你搞的是别的网站的,懂我意思吧,可以分享下但是建议密码别暴露了!
2.直接下载别人的set.pkl文件放入datas文件夹可以直接套用他人的脚本过程非常的人性化.

image.png

下面是部分源码打开的供大家参考!


main.py 这是入口

import threading,sys,os,pickle,time
from codes.panicBuying import PanicBuying
from PyQt5.QtWidgets import QApplication,QMainWindow,QInputDialog,QLineEdit,QMessageBox,QTableWidgetItem
from PyQt5.QtCore import pyqtSignal,QObject,QDateTime
from PyQt5.QtGui import QIcon
from ui.main import Ui_MainWindow
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class Myignals(QObject):
    #定义一种信号,然后确定参数的类型
    log_add=pyqtSignal(str)
def init_window_main():
    global ui_main,window_main
    window_main.setWindowTitle('全能抢购神器-请自觉关闭杀毒软件以免造成意外卡死![url=http://www.52pojie.cn]www.52pojie.cn[/url]')
    window_main.setWindowIcon(QIcon('logo.ico'))
 
    #加载数据
    load()
    # 自动调节宽度
    ui_main.tab_mban.resizeColumnsToContents()
    #绑定按钮信号
    ui_main.bt_openWeb.clicked.connect(openWeb)
    ui_main.bt_start.clicked.connect(true_or_Flase)
    window_main.closeEvent=close
    ui_main.bt_close_all.clicked.connect(reset)
    ui_main.tab_mban.cellChanged.connect(cellChanged)
    ui_main.bt_add.clicked.connect(add_line)
    ui_main.bt_sub.clicked.connect(sub_line)
def reset():
    global driver
    # 关闭所有的浏览器
    for item in driver:
        item.quit()
    close_all=True
    start = False
    ui_main.bt_start.setText('2.全部开始')
    driver=[]
    log_add('重置成功!')
def cellChanged(row, column):
    #自动调节宽度
    ui_main.tab_mban.resizeColumnsToContents()
def add_line():
    count=len(ui_main.tab_mban.selectedItems())
 
    if count > 0:
        #插入一行
        row = ui_main.tab_mban.currentRow()
        print(row)
        ui_main.tab_mban.insertRow(row)
    else:
        ui_main.tab_mban.setRowCount(ui_main.tab_mban.rowCount() + 1)
def sub_line():
 
 
    if ui_main.tab_mban.rowCount() > 0:
        count = len(ui_main.tab_mban.selectedItems())
        if count > 0:
            row = ui_main.tab_mban.currentRow()
            print(row)
            ui_main.tab_mban.removeRow(row)
        else:
            ui_main.tab_mban.setRowCount(ui_main.tab_mban.rowCount() - 1)
def load():
    '''
    读取配置项
    :return:
    '''
    try:
 
        with open(dataPath,'rb')as f:
            setting = pickle.load(f)
 
        sets=setting['items']
        length = len(sets)
        print(setting)
        if length>0:
            #给这些控件初始化
            ui_main.ed_url.setText(setting['url'])
 
            ui_main.dte_time.setDateTime(QDateTime.fromString(setting['dte_time'],'hh:mm:ss'))
            ui_main.cb_sfds.setChecked(setting['cb_sfds'])
            ui_main.cb_tqsx.setChecked(setting['cb_tqsx'])
            #清空
            ui_main.tab_mban.clearContents()
            ui_main.tab_mban.setRowCount(length)
            ui_main.tab_mban.setColumnCount(3)
            print(sets)
            for i,im in enumerate(sets):
                store = QTableWidgetItem(im['store'])
                ui_main.tab_mban.setItem(i, 0, store)
                text=QTableWidgetItem(im['text'])
                ui_main.tab_mban.setItem(i, 1, text)
                css = QTableWidgetItem(im['css'])
                ui_main.tab_mban.setItem(i, 2, css)
 
    except Exception as err:
        print(err)
def save():
    '''
    保存配置项
    :return:
    '''
    items = []
    # 将表格的内容存在items中
    length = ui_main.tab_mban.rowCount()
    for i in range(length):
        try:
 
            items.append({'store': ui_main.tab_mban.item(i, 0).text(),
                          'text': ui_main.tab_mban.item(i, 1).text(),
                          'css': ui_main.tab_mban.item(i, 2).text()})
 
        except:
            pass
    setting={'items':items,
             'url':ui_main.ed_url.text(),
             'dte_time':ui_main.dte_time.text(),
             'cb_sfds':ui_main.cb_sfds.isChecked(),
             'cb_tqsx':ui_main.cb_tqsx.isChecked()}
    with open(dataPath, 'wb')as f:
        pickle.dump(setting, f)
    print(setting)
def close(enent):
    #关闭所有的浏览器
    for item in driver:
        item.quit()
    #保存数据
    save()
def openWeb():
    global driver,ms,close_all
    close_all = False
    #获取链接
    url=ui_main.ed_url.text()
    #获取设置的时间
    time_wait=ui_main.dte_time.text()
    #获取是否定时
    wait=ui_main.cb_sfds.isChecked()
    # 获取是否提前刷新
    refresh = ui_main.cb_tqsx.isChecked()
 
    # 将表格的内容存在items中
    items=[]
    length=ui_main.tab_mban.rowCount()
    for i in range(length):
        items.append({'store':ui_main.tab_mban.item(i,0).text(),'text':ui_main.tab_mban.item(i,1).text(),'css':ui_main.tab_mban.item(i,2).text()})
 
    # 创建浏览器
    try:
        driver.append(webdriver.Chrome())
    except:
        ui_main.ed_log.append('启动浏览器失败!请确定你的有安装谷歌浏览器和根目录有chromedriver.exe,并且版本大于等于87')
        ui_main.ed_log.append('浏览器下载:[url]https://www.google.cn/chrome/'[/url])
        ui_main.ed_log.append('chromedriver.exe下载:[url]https://www.lanzoui.com/isdWeiim1ji'[/url])
        driver=[]
        return
    # 创建线程
    t.append(threading.Thread(target=hw.start,
                              args=(str(len(driver)),
                                    driver[-1],
                                    ms,
                                    url,
                                    items,
                                    time_wait,
                                    wait,
                                    refresh)))
    # 设置主线程关闭时,它也跟着关闭
    t[-1].setDaemon(True)
    # 开始运行
    t[-1].start()
    ui_main.ed_log.append('现在请自己选择好产品的尺寸,规格,型号等参数,然后点全部开始,别关闭浏览器!')
def true_or_Flase():
    global start
    if len(driver)==0:
        log_add('请先增加浏览器')
        return
    if start==True:
        ui_main.bt_start.setText('2.全部开始')
        log_add('已经全部暂停!')
        start = False
    else:
        ui_main.bt_start.setText('2.全部暂停')
 
        log_add('已经全部开始!')
        start =True
    hw.start_kg =start
def log_add(text):
    print(text)
    ui_main.ed_log.append(text)
if __name__ == '__main__':
 
    dataPath='datas/set.pkl'
    # 自定义一个信号
    ms = log_sg = Myignals()
    # 绑定日志更新的信号
    ms.log_add.connect(log_add)
    #实例化抢购对象
    hw = PanicBuying()
    t = []#线程容器
    driver = []#浏览器容器
    start=False#全局暂停和开始的开关
    close_all=False
    app=QApplication(sys.argv)
    window_main = QMainWindow()  # 主界面
    ui_main = Ui_MainWindow()  # 实例化
    ui_main.setupUi(window_main)  # 运行里面的代码
    init_window_main()  # 初始化和对接代码功能
    with open('datas\main.qss', 'r')as f:
        style = f.read()
    window_main.setStyleSheet(style)
 
 
    window_main.show()
    sys.exit(app.exec_())

panicBuying.py

from selenium import webdriver
from PyQt5.QtWidgets import QMainWindow, QTextEdit
 
import time, json
 
 
class PanicBuying():
    def __init__(self):
        self.start_kg = False
        self.close_all = False
 
    def start(self, name, driver, ms, url, items, time_wait, wait, refresh):
        '''
        开始自动多线程抢购
        '''
        try:
            # 超时
            driver.set_page_load_timeout(5000)  # 防止页面加载个没完
            driver.get(url)
            textTrues = []  # 存已经找到的目标
            # 判断是否需要等待
            if wait == True:
                # 如果需要则循环等待这个时间到来,注意了这是电脑时间
                ms.log_add.emit(f'浏览器:{name} 启动时间为:{time_wait},别忘记了点全部开始')
                while True:
                    time.sleep(0.1)
                    if time.strftime("%H:%M:%S", time.localtime()) == time_wait:
                        ms.log_add.emit(f'浏览器:{name} 时间到达!开始运行!')
                        break
 
            # 判断是否需要刷新
            if refresh == True:
                ms.log_add.emit(f'浏览器:{name} 刷新!')
                driver.refresh()
 
            def element_css(selector_text: str, wz_text: str):
                '''
                利用css寻找目标,然后操作
                :return:
                '''
                an = driver.find_element_by_css_selector(selector_text)
                # 判断操作类型
                if wz_text.find('$$') != -1:
                    # 输入文字
                    wz = wz_text.replace('$$', '')
                    if wz_text not in textTrues:
                        an.send_keys(wz)
                        ms.log_add.emit(f'浏览器:{name} 成功帮忙输入了{wz}')
                        return True
 
                else:
                    # 点击按钮
                    an.click()
                    if wz_text not in textTrues :
                        ms.log_add.emit(f'浏览器:{name} 通过CSS定位到{wz_text}按钮')
                        textTrues.append(wz_text)
                return False
 
 
            def element_text(selector_text: str):
                '''
                利用text寻找目标,然后进行操作
                :return:
                '''
                an = driver.find_element_by_xpath(f"//*[text()='{selector_text}']")
                an.click()
                if selector_text not in textTrues:
                    ms.log_add.emit(f'浏览器:{name} 通过名字定位到{selector_text}按钮')
                    textTrues.append(selector_text)
 
            def find_isTrue(wz_text: str):
                '''
                判断是否是成功
                :return:
                '''
                #如果在点击成功列表里面,则发出点击成功信号
                if wz_text in textTrues:
                    ms.log_add.emit(f'浏览器:{name} 点击{wz_text}按钮成功!')
                    return True
                else:
                    return False
            # 正式开始
            for item in items:
                print(item)
                #如果暂停了,就卡死不动
                while self.start_kg == False:
                    # 判断是否要退出
                    if self.close_all == True:
                        ms.log_add.emit(f'浏览器:{name} 已被强制关闭!')
                        return
                time.sleep(0.2)
                # 优先用css来定位
                if item['css'] != '' and item['css'] != None:
                    # 尝试用css定位,如果定位成功则点击,如果定位失败则尝试使用text
                    # 直到点击成功后再下一个目标
                    while True:
                        time.sleep(0.2)
                        # 如果暂停了,就卡死不动
                        while self.start_kg == False:
                            # 判断是否要退出
                            if self.close_all == True:
                                ms.log_add.emit(f'浏览器:{name} 已被强制关闭!')
                                return
                            time.sleep(0.2)
                        try:
                            # 尝试寻找并且尝试操作 如果是输入框,,输入完成后就跳出
                            if element_css(item['css'], item['text'])==True:
                                break
                        except:
                            try:
                                # 尝试寻找并且尝试操作
                                element_text(item['text'])
                            except:#操作失败,可能是没找到或者是已经点成功了
                                # 判断是否是成功
                                if find_isTrue(item['text']) == True:
                                    break
                # 如果没有css则考虑直接使用text来搜索定位.
                elif item['text'] != '' and item['text'] != None:
                    while True:
                        # 如果暂停了,就卡死不动
                        while self.start_kg == False:
                            # 判断是否要退出
                            if self.close_all == True:
                                ms.log_add.emit(f'浏览器:{name} 已被强制关闭!')
                                return
                            time.sleep(0.2)
                        time.sleep(0.2)
                        try:
                            # 尝试寻找并且尝试操作
                            element_text(item['text'])
                        except:#操作失败,可能是没找到或者是已经点成功了
                            # 判断是否是点击成功
                            if find_isTrue(item['text']) == True:
                                break
        except:
            ms.log_add.emit(f'浏览器:{name} 意外关闭!')