| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463 |
- import sys
- from stringprep import in_table_c11
- from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QTabWidget, \
- QLabel, QLineEdit, QTextEdit, QFormLayout, QMessageBox, QTreeWidget, QTreeWidgetItem, QDialog, \
- QVBoxLayout as QDialogVBoxLayout, QLineEdit as QDialogLineEdit, QDialogButtonBox, QCheckBox, QComboBox
- from PyQt5.QtCore import Qt
- import requests as req
- import time, random, numpy as np
- import threading
- import asyncio
- import json
- from PyQt5.QtWidgets import QFileDialog
- from PyQt5.QtCore import pyqtSignal, QObject, pyqtSlot
- import sqlite3
- from CollectibleDialog import CollectibleDialog
- from AppearanceDialog import AppearanceDialog
- from TypeDialog import TypeDialog
- from QualityDialog import QualityDialog
- from CategoryDialog import CategoryDialog
- from SelectLogDialog import SelectLogDialog
- from InitDB import InitDB
- from BUFFAPI import BUFFAPI
- from BUFFXP import BUFFXP
- from datetime import datetime
- from apscheduler.schedulers.blocking import BlockingScheduler
- import datetime
- import time
- from apscheduler.schedulers.background import BackgroundScheduler
- import logging
- from logging.handlers import TimedRotatingFileHandler
- from datetime import datetime, timedelta
- import os
- # 禁用 requests 的日志
- logging.getLogger("requests").setLevel(logging.CRITICAL)
- # 禁用 urllib3 的日志(requests 依赖 urllib3)
- logging.getLogger("urllib3").setLevel(logging.CRITICAL)
- # class CustomTimedRotatingFileHandler(TimedRotatingFileHandler):
- # def doRollover(self):
- # # 获取当前时间
- # current_time = datetime.now() - timedelta(days=1)
- # # 获取当前日期
- # current_date = current_time.strftime('%Y-%m-%d')
- # # 获取当前日志文件名
- # base_filename = os.path.splitext(self.baseFilename)[0]
- # extension = os.path.splitext(self.baseFilename)[1]
- # # 构建新的日志文件名
- # new_filename = f"{base_filename}_{current_date}{extension}"
- # # 如果当前日志文件存在,则重命名
- # if os.path.exists(self.baseFilename):
- # os.rename(self.baseFilename, new_filename)
- # # 调用父类的doRollover方法
- # super().doRollover()
- def detail_namer(default_name):
- # 计算前一天的时间
- current_time = datetime.now() - timedelta(days=1)
- current_date = current_time.strftime('%Y-%m-%d')
- log_file = f'详细日志log/详细日志.{current_date}.txt'
- # 默认情况下,轮转后的文件名会添加日期后缀,这里去掉后缀
- return os.path.join(os.path.dirname(default_name), os.path.basename(log_file))
- def xp_namer(default_name):
- # 计算前一天的时间
- current_time = datetime.now() - timedelta(days=1)
- current_date = current_time.strftime('%Y-%m-%d')
- log_file = f'选品日志log/选品日志.{current_date}.txt'
- # 默认情况下,轮转后的文件名会添加日期后缀,这里去掉后缀
- return os.path.join(os.path.dirname(default_name), os.path.basename(log_file))
- def sh_namer(default_name):
- # 计算前一天的时间
- current_time = datetime.now() - timedelta(days=1)
- current_date = current_time.strftime('%Y-%m-%d')
- log_file = f'扫货日志log/扫货日志.{current_date}.txt'
- # 默认情况下,轮转后的文件名会添加日期后缀,这里去掉后缀
- return os.path.join(os.path.dirname(default_name), os.path.basename(log_file))
- def gm_namer(default_name):
- # 计算前一天的时间
- current_time = datetime.now() - timedelta(days=1)
- current_date = current_time.strftime('%Y-%m-%d')
- log_file = f'购买日志log/购买日志.{current_date}.txt'
- # 默认情况下,轮转后的文件名会添加日期后缀,这里去掉后缀
- return os.path.join(os.path.dirname(default_name), os.path.basename(log_file))
- class MainWindow(QMainWindow):
- # 定义一个信号,用于传递日志信息
- log_added = pyqtSignal(str, str, str, str, str, str, str, str)
- def namer(default_name,file_path,file_name):
- # 计算前一天的时间
- current_time = datetime.now() - timedelta(days=1)
- current_date = current_time.strftime('%Y-%m-%d')
- log_file = f'{file_path}/{file_name}.{current_date}.txt'
- # 默认情况下,轮转后的文件名会添加日期后缀,这里去掉后缀
- return os.path.join(os.path.dirname(default_name), os.path.basename(log_file))
- def __init__(self):
- super().__init__()
- # 设置一个选品已启动的标志
- self.xp_started = False
- # 设置一个选品停止的flag
- self.stop_selecting_flag = False
- # 向BUFF选品日志列表中写内容的槽函数
- self.log_added.connect(self._add_select_log) # 连接信号到槽函数
- # 初始化数据库
- InitDB.init_db()
- self.xp_goodsurl = 'https://buff.163.com/api/market/goods'
- self.xp_getPaintwearChoicesUrl = 'https://buff.163.com/api/market/goods/info?goods_id='
- self.xp_getPriceUrl = 'https://buff.163.com/api/market/goods/sell_order?game=csgo&page_num=1&sort_by=price.asc&goods_id='
- self.xp_my_headers = {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
- "Host": "buff.163.com",
- "Referer": "https://buff.163.com/market/?game=csgo",
- "X-Requested-With": "XMLHttpRequest"
- }
- # todo 为了测试 page_size = 1
- #self.sh_getToBuyUrl = 'https://buff.163.com/api/market/goods/sell_order?game=csgo&allow_epay=1&allow_tradable_cooldown=1&page_num=1&page_size=1&sort_by=price.asc&goods_id='
- self.sh_buyGoodsUrl = 'https://buff.163.com/api/market/goods/buy'
- self.sh_getToBuyUrl = 'https://buff.163.com/api/market/goods/sell_order?game=csgo&allow_epay=1&allow_tradable_cooldown=1&page_num=1&page_size=95&sort_by=price.asc&goods_id='
- self.sh_fbjUrl= 'https://buff.163.com/api/market/bill_order/ask_seller_to_send_offer'
- self.sh_my_headers = {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
- "Host": "buff.163.com",
- "Referer": "https://buff.163.com/market/?game=csgo",
- "X-Requested-With": "XMLHttpRequest"
- }
- # 配置日志记录器
- self.logger_cmd = logging.getLogger('logger_cmd')
- self.logger_cmd.setLevel(logging.DEBUG)
- # 配置控制台处理器和格式器
- self.console_handler = logging.StreamHandler()
- self.console_handler.setLevel(logging.DEBUG)
- self.console_formatter = logging.Formatter('[%(asctime)s] %(message)s')
- self.console_handler.setFormatter(self.console_formatter)
- # 将处理器添加到记录器中
- self.logger_cmd.addHandler(self.console_handler)
- self.logger_cmd.propagate = False
- # 创建一个选品logger
- self.detail_logger = logging.getLogger('detailLogger')
- self.detail_logger.setLevel(logging.DEBUG) # 设置日志级别
- # 创建一个handler,用于写入文件,并根据时间自动轮换日志文件
- detail_handler = TimedRotatingFileHandler('详细日志log/详细日志.txt', when='midnight', interval=1, backupCount=30,encoding='utf-8')
- detail_handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s'))
- detail_handler.namer = detail_namer
- # 添加handler到logger
- self.detail_logger.addHandler(detail_handler)
- self.detail_logger.propagate = False
- # 创建一个选品logger
- self.xp_logger = logging.getLogger('xpLogger')
- self.xp_logger.setLevel(logging.DEBUG) # 设置日志级别
- # 创建一个handler,用于写入文件,并根据时间自动轮换日志文件
- xp_handler = TimedRotatingFileHandler('选品日志log/选品日志.txt', when='midnight', interval=1, backupCount=30,encoding='utf-8')
- xp_handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s'))
- xp_handler.namer = xp_namer
- # 添加handler到logger
- self.xp_logger.addHandler(xp_handler)
- self.xp_logger.propagate = False
- # 创建扫货logger
- self.sh_logger = logging.getLogger('shLogger')
- self.sh_logger.setLevel(logging.DEBUG) # 设置日志级别
- # 创建一个handler,用于写入文件,并根据时间自动轮换日志文件
- sh_handler = TimedRotatingFileHandler('扫货日志log/扫货日志.txt', when='midnight', interval=1, backupCount=30,encoding='utf-8')
- sh_handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s'))
- sh_handler.namer = sh_namer
- # 添加handler到logger
- self.sh_logger.addHandler(sh_handler)
- self.sh_logger.propagate = False
- # 创建购买logger
- self.gm_logger = logging.getLogger('gmLogger')
- self.gm_logger.setLevel(logging.DEBUG) # 设置日志级别
- # 创建一个handler,用于写入文件,并根据时间自动轮换日志文件
- gm_handler = TimedRotatingFileHandler('购买日志log/购买日志.txt', when='midnight', interval=1, backupCount=30,encoding='utf-8')
- gm_handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s'))
- gm_handler.namer = gm_namer
- # 添加handler到logger
- self.gm_logger.addHandler(gm_handler)
- self.gm_logger.propagate = False
- # 初始化 phone_edit_map
- # self.setup_phone_edit_map()
- # 设置窗口标题和大小
- self.setWindowTitle("BUFF选品扫货")
- self.setGeometry(100, 100, 200, 200)
- # 创建一个垂直布局
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保垂直布局内容靠左对齐
- # 创建一个水平布局来放置按钮
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保水平布局内容靠左对齐
- # 创建两个按钮
- self.button1 = QPushButton("选品")
- # 增加停止选品和停止扫货按钮
- self.stop_select_button = QPushButton("停止选品")
- button_layout.addWidget(self.button1)
- button_layout.addWidget(self.stop_select_button)
- # 连接按钮的点击事件
- self.button1.clicked.connect(self.show_selected_phone_number)
- self.stop_select_button.clicked.connect(self.stop_selecting) # 新增连接停止选品按钮的点击事件
- self.button_sh = QPushButton("扫货")
- button_layout.addWidget(self.button_sh)
- self.button_sh.clicked.connect(self.beginSH)
- self.button_stop_sh = QPushButton("停止扫货")
- button_layout.addWidget(self.button_stop_sh)
- self.button_stop_sh.clicked.connect(self.stopSH)
- # 将水平布局添加到垂直布局中
- layout.addLayout(button_layout)
- # 创建一个Tab容器
- self.tab_widget = QTabWidget()
- # 向Tab容器中添加10个标签页
- for i in range(1, 11): # 修改循环范围以添加第11个标签页
- tab = QWidget()
- tab_layout = QVBoxLayout()
- tab_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保标签页布局内容靠左对齐
- if i == 1:
- form_layout = self.create_account_info_form("选品")
- tab_layout.addLayout(form_layout)
- elif i == 2:
- tree_layout = self.create_category_info_form()
- tab_layout.addLayout(tree_layout)
- elif i == 3:
- quality_layout = self.create_quality_info_form()
- tab_layout.addLayout(quality_layout)
- elif i == 4:
- type_layout = self.create_type_info_form()
- tab_layout.addLayout(type_layout)
- elif i == 5:
- appearance_layout = self.create_appearance_info_form()
- tab_layout.addLayout(appearance_layout)
- elif i == 6:
- collectible_layout = self.create_collectible_info_form()
- tab_layout.addLayout(collectible_layout)
- elif i == 7:
- config_layout = self.create_config_info_form("选品")
- tab_layout.addLayout(config_layout)
- elif i == 8:
- select_log_layout = self.create_select_log_info_form() # 添加BUFF选品日志标签页
- tab_layout.addLayout(select_log_layout)
- elif i == 9:
- shzhtab_layout = self.setup_shzhtab()
- tab_layout.addLayout(shzhtab_layout)
- elif i == 10:
- shpztab_layout = self.setup_shpztab()
- tab_layout.addLayout(shpztab_layout)
- else:
- label = QLabel(f"这是标签页 {i}")
- tab_layout.addWidget(label)
- tab.setLayout(tab_layout)
- if i == 1:
- self.tab_widget.addTab(tab, "选品账号")
- elif i == 2:
- self.tab_widget.addTab(tab, "品类")
- elif i == 3:
- self.tab_widget.addTab(tab, "品质")
- elif i == 4:
- self.tab_widget.addTab(tab, "TYPE")
- elif i == 5:
- self.tab_widget.addTab(tab, "外观")
- elif i == 6:
- self.tab_widget.addTab(tab, "收藏品")
- elif i == 7:
- self.tab_widget.addTab(tab, "选品配置")
- elif i == 8:
- self.tab_widget.addTab(tab, "选品日志")
- elif i == 9:
- self.tab_widget.addTab(tab, "扫货账号")
- elif i == 10:
- self.tab_widget.addTab(tab, "扫货配置")
- # 将Tab容器添加到布局中
- layout.addWidget(self.tab_widget)
- # 创建一个中心部件,并将布局设置为中心部件的布局
- container = QWidget()
- container.setLayout(layout)
- # 将中心部件设置为主窗口的中心部件
- self.setCentralWidget(container)
- # 自动开启选品
- # 获取定时时间
- cron_time = self.cron_time_label_edit.text()
- scheduler = BackgroundScheduler()
- # 设置每天早上9点执行任务(使用cron表达式)
- #cron_time 的格式为10:11,11:12,12:13
- #遍历cron_time,先要判断cron_time是否为空
- if cron_time:
- cron_times = cron_time.split(',')
- for cron_time_item in cron_times:
- if cron_time_item:
- #如果cron_time_item中没有:则pass
- if ':' in cron_time_item:
- self.detail_logger.debug(f'启动选品每天{cron_time_item}定时任务...')
- scheduler.add_job(self.show_selected_phone_number, 'cron', hour=int(cron_time_item.split(':')[0]), minute=int(cron_time_item.split(':')[1]), second=0)
- #scheduler.add_job(self.show_selected_phone_number, 'cron', hour=int(cron_time), minute=8, second=30)
- try:
- # print(f'启动选品每天{cron_time}定时任务...')
- scheduler.start()
- except (KeyboardInterrupt, SystemExit):
- self.detail_logger.debug('已取消选品每天{cron_time}定时任务')
- # 选品按钮绑定的方法
- def show_selected_phone_number(self):
- if self.xp_started :
- self.detail_logger.debug('选品已开启,本次尝试自动关闭')
- return
- # 查询检索选品入参
- if not BUFFXP.checkBuffXPParams(self):
- self.detail_logger.debug('选品入参异常,请重新调整后再选品')
- return
- try:
- thread_searchGoods = threading.Thread(target=self.firstSelectGoods)
- thread_searchGoods.start()
- except Exception as e:
- self.detail_logger.debug(f"选品进程异常: {e}")
- # 创建一个方法,将数据库中select_logs数据保存到本地的xpback文件中,文件名称XPRZ_YYYYMMDDHHMMDD.json
- # 选品逻辑
- def firstSelectGoods(self):
- self.xp_started = True
- self.logger_cmd.debug('开始选品')
- self.detail_logger.debug('开始选品')
- # 先停扫货,设置扫货停止标志为True,选品之前先暂停扫货
- self.logger_cmd.debug(f'暂停扫货进程')
- self.detail_logger.debug(f'暂停扫货进程....')
- self.stop_shopping_flag = True
- time.sleep(float(self.shpz_pause_time_edit.text()))
- self.logger_cmd.debug(f'扫货进程暂停完成,开启选品')
- self.detail_logger.debug(f'扫货进程暂停完成,开启选品')
- # 设置选品停止标志为False
- self.stop_selecting_flag = False
- # 扫货、停止扫货和选品按钮 按钮不可点击
- self.button_sh.setEnabled(False)
- self.button_stop_sh.setEnabled(False)
- self.button1.setEnabled(False)
- # 将已选品的记录保存到文件中,用于后续的选品记录,然后情况选品记录的表
- # 保存选品日志到本地文件
- SelectLogDialog.export_selected_logs_tolocal(self)
- # 删除所有选品日志信息
- SelectLogDialog.delete_all_select_logs(self)
- # 删除所有的日志的记录self.select_log_tree_widget
- self.select_log_tree_widget.clear()
- # 已经选品的数量
- self.searchedGoodsNum = 0
- # 已经选品成功的数量
- self.search_success_count = 0
- # 获取商品选取API的入参list
- BUFFXP.get_goods_param_list(self)
- # 设定暂停起始时间
- self.last_xp_request_time = 0
- try:
- xiesi_tag = 0
- # 无限循环 改成 只循环两次
- while xiesi_tag < 2:
- xiesi_tag += 1
- # 待判断的商品列表
- self.need_check_goods_list = []
- # 选品cookie的状态池子
- self.cookie_status = {}
- # self.cookie_text 中有多个cookie的值,用换行分开的
- self.cookie_text_list = self.cookie_text.split('\n')
- #判断退出条件
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- return
- # 判断是否达到了成功的数量限制,如果达到,则跳出循环
- if self.stop_condition == '按照成功数量':
- self.detail_logger.debug(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- if int(self.success_count) <= int(self.search_success_count):
- return
- else:
- # 按照选品数量来判断是否要停止
- self.detail_logger.debug(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- if int(self.scan_count) <= int(self.searchedGoodsNum):
- return
- # 从1开始遍历到self.max_page
- for page in range(1, int(self.max_page)+1):
- try:
- #判断退出条件
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- return
- self.detail_logger.debug(f"开始请求第{page}/{self.max_page}页商品数据")
- # 开始时间为当前时间
- # 暂停时间
- if page != 1:
- self.detail_logger.debug(f"暂停 {float(self.pause_time):.2f} seconds 再进行检索商品数据..")
- time.sleep(float(self.pause_time))
- # 检索数据是否循环的条件
- self.search_goods_stop_flag = True
- # 404异常次数
- self.search_goods_404_times = 0
- # 请求商品数据,如果返回的code为'System Error',则继续用当前的cookie请求,连续3次,则跳出循环。如果返回的code为'Captcha Validate Required',则用下一个cookie请求,cookie连续的3次被标记为超时,则此cookie标志为无效,当所有的cookie都标记为无效时,退出程序
- temp_cookie_i = 0
- temp_cookie_length = len(self.cookie_text_list)
- while self.search_goods_stop_flag:
- # 判断退出条件
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- return
- # 遍历self.cookie_status中元素,self.cookie_text为主键的值,如果次数为3,则删除self.cookie_text中这个cookie
- for key, value in self.cookie_status.items():
- if value >= int(self.needed_msg_check_try_times):
- # self.cookie_text_list 存在 key
- if key in self.cookie_text_list:
- # 删除self.cookie_text_list中key对应的值
- self.cookie_text_list.remove(key)
- self.detail_logger.debug(f"cookie: {key},超时异常的次数{value},删除")
- # 当self.cookie_text_list长度为0时,则退出程序
- if len(self.cookie_text_list) == 0:
- self.detail_logger.debug('所有cookie都不可用,退出程序')
- return
- # 更新选品cookie ,每一次请求轮流取其中一个
- self.temp_cookie_text = self.cookie_text_list[(page+temp_cookie_i-1) % len(self.cookie_text_list)]
- self.xp_my_headers.update({
- 'Cookie': self.temp_cookie_text
- })
- self.search_goods_param_list['page_num'] = page
- self.logger_cmd.debug(f'正在使用{self.temp_cookie_text}')
- self.logger_cmd.debug(f'请求第{page}/{self.max_page}页商品数据')
- search_goods_res = req.get(url=self.xp_goodsurl, headers=self.xp_my_headers,params=self.search_goods_param_list)
- self.detail_logger.debug(f"遍历商品接口请求返回报文中的CODE:{search_goods_res.json()['code']} ,遍历商品接口请求返回报文:{search_goods_res.text.strip()[:50]}")
- # 返回成功,则跳出循环
- if search_goods_res.json()['code'] == 'OK':
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- # 将遍历结果的商品数据记录保存
- data = search_goods_res.json()['data']
- self.need_check_goods_list.extend(data['items'])
- break
- # 返回404异常,继续用这个cookie请求,超过了次数则退出
- elif search_goods_res.json()['code'] == 'System Error' :
- # 404异常次数加1
- self.search_goods_404_times += 1
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- if self.search_goods_404_times >= temp_cookie_length:
- self.detail_logger.debug(f"有效的cookie都提示404异常,异常次数:{str(self.search_goods_404_times)}, 跳出循环继续下一个页面检索")
- break
- else:
- temp_cookie_i += 1
- # 404异常时候,暂停一会再执行
- self.logger_cmd.debug(f'访问频繁,等待{float(self.pause_time) + 30}秒')
- time.sleep(float(self.pause_time) + 30)
- continue
- # 返回需要短信验证
- elif search_goods_res.json()['code'] == 'Captcha Validate Required' or search_goods_res.json()['code'] == 'Login Required' or search_goods_res.json()['code'] == 'Action Forbidden':
- if search_goods_res.json()['code'] == 'Login Required':
- self.logger_cmd.debug(f'需要登陆')
- # time.sleep(float(self.needed_msg_check_pause_time))
- self.search_goods_404_times = 0
- #判断self.cookie_status是否有key为self.temp_cookie_text
- if self.temp_cookie_text not in self.cookie_status:
- if search_goods_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数1,等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = 1
- else:
- if search_goods_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数{int(self.cookie_status[self.temp_cookie_text]) + 1},等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = int(self.cookie_status[self.temp_cookie_text]) + 1
- time.sleep(float(self.needed_msg_check_pause_time))
- # 从self.cookie_text_list获取下一个cookie,因为此cookie需要从list中移除,所以自动就是下一个,如果没有从list中移除,需要+1
- if self.cookie_status[self.temp_cookie_text] >= int(self.needed_msg_check_try_times):
- self.logger_cmd.debug(f'异常{int(self.needed_msg_check_try_times)}次,暂停!')
- temp_cookie_i += 0
- else:
- temp_cookie_i += 1
- else:
- # 其他异常的情况,直接跳出
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- break
- except Exception as e:
- self.detail_logger.debug(f"检索商品数据异常: {e}")
- finally:
- pass
- # 根据id去重
- # 使用字典去重
- unique_goods_dict = {item['id']: item for item in self.need_check_goods_list}
- # 将字典转换回列表
- self.need_check_goods_list = list(unique_goods_dict.values())
- # 遍历self.xp_delete_ids,用#号分割后,将self.need_check_goods_list中存在的这些id去除
- xp_delete_ids_set = set(self.xp_delete_ids.split('#'))
- self.need_check_goods_list = [item for item in self.need_check_goods_list if str(item['id']) not in xp_delete_ids_set]
- # 根据最低销售量,将不满足条件的商品剔除
- check_sell_num = int(self.sell_num_label_edit.text())
- self.need_check_goods_list = [item for item in self.need_check_goods_list if item['sell_num'] >= int(check_sell_num)]
- if len(self.need_check_goods_list) <=0:
- continue
- # 循环遍历商品,获取磨损度区间,获取最低价和获取磨损区间内的最低价
- for g_i_i in range(len(self.need_check_goods_list)):
- try:
- #判断退出条件
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- return
- # 判断是否达到了成功的数量限制,如果达到,则跳出循环
- if self.stop_condition == '按照成功数量':
- self.detail_logger.debug(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- if int(self.success_count) <= int(self.search_success_count):
- return
- else:
- # 按照选品数量来判断是否要停止
- self.detail_logger.debug(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- if int(self.scan_count) <= int(self.searchedGoodsNum):
- return
- # 1、获取磨损信息
- self.detail_logger.debug(f"开始获取商品id: {self.need_check_goods_list[g_i_i]['id']} 的磨损数据")
- # 暂停时间
- self.detail_logger.debug(f"暂停 {float(self.pause_time):.2f} seconds 在进行..")
- time.sleep(float(self.pause_time))
- # 检索数据是否停止的条件
- self.search_goods_stop_flag = True
- # 404异常次数
- self.search_goods_404_times = 0
- # 请求商品数据,如果返回的code为'System Error',则继续用当前的cookie请求,连续3次,则跳出循环。如果返回的code为'Captcha Validate Required',则用下一个cookie请求,cookie连续的3次被标记为超时,则此cookie标志为无效,当所有的cookie都标记为无效时,退出程序
- temp_cookie_i = 0
- self.paintwear_choices = []
- temp_cookie_length = len(self.cookie_text_list)
- while self.search_goods_stop_flag:
- # 判断退出条件
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- return
- # 遍历self.cookie_status中元素,self.cookie_text为主键的值,如果次数为3,则删除self.cookie_text中这个cookie
- self.detail_logger.debug(f"self.cookie_status:{self.cookie_status}")
- for key, value in self.cookie_status.items():
- self.detail_logger.debug(f"key is {key}, value is {value} self.needed_msg_check_try_times is { int(self.needed_msg_check_try_times)}")
- if value >= int(self.needed_msg_check_try_times):
- if key in self.cookie_text_list:
- # 删除self.cookie_text_list中key对应的值
- self.cookie_text_list.remove(key)
- self.detail_logger.debug(f"cookie: {key},超时异常的次数{value},删除")
- # 当self.cookie_text_list长度为0时,则退出程序
- if len(self.cookie_text_list) == 0:
- self.detail_logger.debug('所有cookie都超时,退出程序')
- return
- # 更新选品cookie ,每一次请求轮流取其中一个
- self.temp_cookie_text = self.cookie_text_list[(g_i_i+temp_cookie_i) % len(self.cookie_text_list)]
- self.xp_my_headers.update({
- 'Cookie': self.temp_cookie_text
- })
- self.xp_logger.debug(f'[选品]正在使用:{self.temp_cookie_text} 名称:{self.need_check_goods_list[g_i_i]["name"]},ID:{self.need_check_goods_list[g_i_i]["id"]} ')
- self.logger_cmd.debug(f'[选品]正在使用:{self.temp_cookie_text} 检索 名称:{self.need_check_goods_list[g_i_i]["name"]},ID:{self.need_check_goods_list[g_i_i]["id"]} ')
- goods_id = self.need_check_goods_list[g_i_i]['id']
- paintware_res = req.get(url=self.xp_getPaintwearChoicesUrl + str(goods_id), headers=self.xp_my_headers)
- self.detail_logger.debug(f"获取商品id: {goods_id} 磨损区间请求返回报文中的CODE:{paintware_res.json()['code']} ,获取商品id: {goods_id} 磨损区间请求返回报文:{paintware_res.text.strip()[:50]}")
- # 返回成功,则跳出循环
- if paintware_res.json()['code'] == 'OK':
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- # 将遍历结果的商品数据记录保存
- data = paintware_res.json()['data']
- self.paintwear_choices = data['paintwear_choices']
- break
- # 返回404异常,继续用这个cookie请求,超过了次数则退出
- elif paintware_res.json()['code'] == 'System Error':
- # 404异常次数加1
- self.search_goods_404_times += 1
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- if self.search_goods_404_times >= temp_cookie_length:
- self.detail_logger.debug(f"有效的cookie都提示404异常,异常次数:{str(self.search_goods_404_times)}, 跳出循环继续下一个商品检索")
- break
- else:
- temp_cookie_i += 1
- # 404异常时候,暂停一会再执行
- self.logger_cmd.debug(f'访问频繁,等待{float(self.pause_time) + 30}秒')
- time.sleep(float(self.pause_time) + 30)
- continue
- # 返回需要短信验证
- elif paintware_res.json()['code'] == 'Captcha Validate Required' or paintware_res.json()['code'] == 'Login Required' or paintware_res.json()['code'] == 'Action Forbidden' :
- if paintware_res.json()['code'] == 'Login Required':
- self.logger_cmd.debug(f'需要登陆')
- # time.sleep(float(self.needed_msg_check_pause_time))
- self.search_goods_404_times = 0
- #判断self.cookie_status是否有key为self.temp_cookie_text
- if self.temp_cookie_text not in self.cookie_status:
- if paintware_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数1,等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = 1
- else:
- if paintware_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数{int(self.cookie_status[self.temp_cookie_text]) + 1},等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = int(self.cookie_status[self.temp_cookie_text]) + 1
- time.sleep(float(self.needed_msg_check_pause_time))
- # 从self.cookie_text_list获取下一个cookie,因为此cookie需要从list中移除,所以自动就是下一个,如果没有从list中移除,需要+1
- if self.cookie_status[self.temp_cookie_text] >= int(self.needed_msg_check_try_times):
- self.logger_cmd.debug(f'异常{int(self.needed_msg_check_try_times)}次,暂停!')
- temp_cookie_i += 0
- else:
- temp_cookie_i += 1
- else:
- # 其他异常的情况,直接跳出
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- break
- # 商品磨损区间长度小于等于0 ,continue
- if len(self.paintwear_choices) <= 0:
- continue
- # 1、先获取全磨损的最低价 170
- self.detail_logger.debug(f"开始获取商品id: {self.need_check_goods_list[g_i_i]['id']} 的全磨损的最低价")
- # 暂停时间
- self.detail_logger.debug(f"暂停 {float(self.pause_time):.2f} seconds 再进行全磨损的最低价请求..")
- time.sleep(float(self.pause_time))
- # 检索数据是否停止的条件
- self.search_goods_stop_flag = True
- # 404异常次数
- self.search_goods_404_times = 0
- # 请求商品数据,如果返回的code为'System Error',则继续用当前的cookie请求,连续3次,则跳出循环。如果返回的code为'Captcha Validate Required',则用下一个cookie请求,cookie连续的3次被标记为超时,则此cookie标志为无效,当所有的cookie都标记为无效时,退出程序
- temp_cookie_i = 0
- temp_cookie_length = len(self.cookie_text_list)
- while self.search_goods_stop_flag:
- # 判断退出条件
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- return
- # 遍历self.cookie_status中元素,self.cookie_text为主键的值,如果次数为3,则删除self.cookie_text中这个cookie
- for key, value in self.cookie_status.items():
- if value >= int(self.needed_msg_check_try_times):
- if key in self.cookie_text_list:
- # 删除self.cookie_text_list中key对应的值
- self.cookie_text_list.remove(key)
- self.detail_logger.debug(f"cookie: {key},超时异常的次数{value},删除")
- # 当self.cookie_text_list长度为0时,则退出程序
- if len(self.cookie_text_list) == 0:
- self.detail_logger.debug('所有cookie都超时,退出程序')
- return
- # 更新选品cookie ,每一次请求轮流取其中一个
- self.temp_cookie_text = self.cookie_text_list[(g_i_i+temp_cookie_i) % len(self.cookie_text_list)]
- self.xp_my_headers.update({
- 'Cookie': self.temp_cookie_text
- })
- goods_id = self.need_check_goods_list[g_i_i]['id']
- self.goods_min_price = 0
- url = self.xp_getPriceUrl + str(goods_id)
- paintware_minprice_res = req.get(url=url, headers=self.xp_my_headers)
- self.logger_cmd.debug(f'正在使用{self.temp_cookie_text}')
- # self.logger_cmd.debug(f"获取商品id{goods_id}全磨损区间最低价")
- self.detail_logger.debug(f"获取商品id: {goods_id} 全磨损区间最低价请求返回报文中的CODE:{paintware_minprice_res.json()['code']} ,获取商品id: {goods_id} 全磨损区间最低价请求返回报文:{paintware_minprice_res.text.strip()[:50]}")
- # 返回成功,则跳出循环
- if paintware_minprice_res.json()['code'] == 'OK':
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- # 将遍历结果的商品数据记录保存
- data = paintware_minprice_res.json()['data']
- self.goods_min_price = data['items'][0]['price']
- self.detail_logger.debug(f"获取商品id: {goods_id} 全磨损区间最低价:{self.goods_min_price}")
- self.logger_cmd.debug(f"获取商品id: {goods_id} 全磨损区间最低价:{self.goods_min_price}")
- break
- # 返回404异常,继续用这个cookie请求,超过了次数则退出
- elif paintware_minprice_res.json()['code'] == 'System Error':
- # 404异常次数加1
- self.search_goods_404_times += 1
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- if self.search_goods_404_times >= temp_cookie_length:
- self.detail_logger.debug(f"有效的cookie都提示404异常,异常次数:{str(self.search_goods_404_times)}, 跳出循环继续商品其他区间检索")
- break
- else:
- temp_cookie_i += 1
- # 404异常时候,暂停一会再执行
- self.logger_cmd.debug(f'访问频繁,等待{float(self.pause_time) + 30}秒')
- time.sleep(float(self.pause_time) + 30)
- continue
- # 返回需要短信验证
- elif paintware_minprice_res.json()['code'] == 'Captcha Validate Required' or paintware_minprice_res.json()['code'] == 'Login Required' or paintware_minprice_res.json()['code'] == 'Action Forbidden' :
- if paintware_minprice_res.json()['code'] == 'Login Required':
- self.logger_cmd.debug(f'需要登陆')
- # time.sleep(float(self.needed_msg_check_pause_time))
- self.search_goods_404_times = 0
- #判断self.cookie_status是否有key为self.temp_cookie_text
- if self.temp_cookie_text not in self.cookie_status:
- if paintware_minprice_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数1,等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = 1
- else:
- if paintware_minprice_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数{int(self.cookie_status[self.temp_cookie_text]) + 1},等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = int(self.cookie_status[self.temp_cookie_text]) + 1
- time.sleep(float(self.needed_msg_check_pause_time))
- # 从self.cookie_text_list获取下一个cookie,因为此cookie需要从list中移除,所以自动就是下一个,如果没有从list中移除,需要+1
- if self.cookie_status[self.temp_cookie_text] >= int(self.needed_msg_check_try_times):
- self.logger_cmd.debug(f'异常{int(self.needed_msg_check_try_times)}次,暂停!')
- temp_cookie_i += 0
- else:
- temp_cookie_i += 1
- else:
- # 其他异常的情况,直接跳出
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- break
- if float(self.goods_min_price) <=0 :
- continue
- # 遍历磨损区间,获取磨损区间最低价格
- # 每个磨损区间的最低价
- min_price_list = []
- # 2、获取每个磨损区间的最低价 270 260 230 240 170
- for i3 in range(len(self.paintwear_choices)):
- # 做终止判断是否点击了停止选品按钮
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- return
- # 1、先获取全磨损的最低价 170
- self.detail_logger.debug(f"开始获取商品id: {self.need_check_goods_list[g_i_i]['id']} 的磨损区间磨损区间{self.paintwear_choices[i3][0]}--{self.paintwear_choices[i3][1]}的最低价")
- # 开始时间为当前时间
- # 暂停时间
- self.detail_logger.debug(f"暂停 {float(self.pause_time):.2f} seconds 再进行磨损区间磨损区间{self.paintwear_choices[i3][0]}--{self.paintwear_choices[i3][1]}的最低价请求..")
- time.sleep(float(self.pause_time))
- # 检索数据是否停止的条件
- self.search_goods_stop_flag = True
- # 404异常次数
- self.search_goods_404_times = 0
- # 请求商品数据,如果返回的code为'System Error',则继续用当前的cookie请求,连续3次,则跳出循环。如果返回的code为'Captcha Validate Required',则用下一个cookie请求,cookie连续的3次被标记为超时,则此cookie标志为无效,当所有的cookie都标记为无效时,退出程序
- temp_cookie_i = 0
- temp_cookie_length = len(self.cookie_text_list)
- min_price_list.append(
- {
- 'min_wear': self.paintwear_choices[i3][0],
- 'max_wear': self.paintwear_choices[i3][1],
- 'min_price': float(0)
- }
- )
- while self.search_goods_stop_flag:
- # 判断退出条件
- if self.stop_selecting_flag:
- self.detail_logger.debug('停止选品')
- return
- # 遍历self.cookie_status中元素,self.cookie_text为主键的值,如果次数为3,则删除self.cookie_text中这个cookie
- for key, value in self.cookie_status.items():
- if value >= int(self.needed_msg_check_try_times):
- if key in self.cookie_text_list:
- # 删除self.cookie_text_list中key对应的值
- self.cookie_text_list.remove(key)
- self.detail_logger.debug(f"cookie: {key},超时异常的次数{value},删除")
- # 当self.cookie_text_list长度为0时,则退出程序
- if len(self.cookie_text_list) == 0:
- self.detail_logger.debug('所有cookie都超时,退出程序')
- return
- # 更新选品cookie ,每一次请求轮流取其中一个
- self.temp_cookie_text = self.cookie_text_list[(g_i_i+temp_cookie_i) % len(self.cookie_text_list)]
- self.xp_my_headers.update({
- 'Cookie': self.temp_cookie_text
- })
- goods_id = self.need_check_goods_list[g_i_i]['id']
- url = self.xp_getPriceUrl + str(goods_id)
- # min_paint_wear 不为空
- if self.paintwear_choices[i3][0] != '':
- self.detail_logger.debug('min_paint_wear 最低磨损值 不为空')
- url += '&min_paintwear=' + str(self.paintwear_choices[i3][0])
- # max_paint_wear 不为空
- if self.paintwear_choices[i3][1] != '':
- self.detail_logger.debug('max_paint_wear 最高磨损值 不为空')
- url += '&max_paintwear=' + str(self.paintwear_choices[i3][1])
- paintware_minprice_res = req.get(url=url, headers=self.xp_my_headers)
- self.logger_cmd.debug(f'正在使用{self.temp_cookie_text}')
- # self.logger_cmd.debug(f"获取商品id{goods_id}磨损区间{self.paintwear_choices[i3][0]}--{self.paintwear_choices[i3][1]}最低价")
- self.detail_logger.debug(f"获取商品id: {goods_id} 磨损区间{self.paintwear_choices[i3][0]}--{self.paintwear_choices[i3][1]}最低价请求返回报文中的CODE:{paintware_minprice_res.json()['code']} ,获取商品id: {goods_id} 磨损区间{self.paintwear_choices[i3][0]}--{self.paintwear_choices[i3][1]}最低价请求返回报文:{paintware_minprice_res.text.strip()[:50]}")
- # 返回成功,则跳出循环
- if paintware_minprice_res.json()['code'] == 'OK':
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- # 将遍历结果的商品数据记录保存
- data = paintware_minprice_res.json()['data']
- self.detail_logger.debug(f"获取商品id: {goods_id} 磨损区间{self.paintwear_choices[i3][0]}--{self.paintwear_choices[i3][1]}最低价:{float(data['items'][0]['price'])}")
- self.logger_cmd.debug(f"获取商品id: {goods_id} 磨损区间{self.paintwear_choices[i3][0]}--{self.paintwear_choices[i3][1]}最低价:{float(data['items'][0]['price'])}")
- # 遍历min_price_list,如果min_wear的值为self.paintwear_choices[i3][0],max_wear的值为self.paintwear_choices[i3][1],则将min_price的值更新为float(data['items'][0]['price'])
- for ii2 in range(len(min_price_list)):
- if min_price_list[ii2]['min_wear'] == self.paintwear_choices[i3][0] and min_price_list[ii2]['max_wear'] == self.paintwear_choices[i3][1]:
- min_price_list[ii2]['min_price'] = float(data['items'][0]['price'])
- break
- # # todo
- # min_price_list.append(
- # {
- # 'min_wear': self.paintwear_choices[i3][0],
- # 'max_wear': self.paintwear_choices[i3][1],
- # 'min_price': float(data['items'][0]['price'])
- # })
- break
- # 返回404异常,继续用这个cookie请求,超过了次数则退出
- elif paintware_minprice_res.json()['code'] == 'System Error':
- # 404异常次数加1
- self.search_goods_404_times += 1
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- if self.search_goods_404_times >= temp_cookie_length:
- self.detail_logger.debug(f"有效的cookie都提示404异常,异常次数:{str(self.search_goods_404_times)}, 跳出循环继续商品其他区间检索")
- break
- else:
- temp_cookie_i += 1
- # 404异常时候,暂停一会再执行
- self.logger_cmd.debug(f'访问频繁,等待{float(self.pause_time) + 30}秒')
- time.sleep(float(self.pause_time) + 30)
- continue
- # 返回需要短信验证
- elif paintware_minprice_res.json()['code'] == 'Captcha Validate Required' or paintware_minprice_res.json()['code'] == 'Login Required' or paintware_minprice_res.json()['code'] == 'Action Forbidden':
- if paintware_minprice_res.json()['code'] == 'Login Required':
- self.logger_cmd.debug(f'需要登陆')
- # time.sleep(float(self.needed_msg_check_pause_time))
- self.search_goods_404_times = 0
- #判断self.cookie_status是否有key为self.temp_cookie_text
- if self.temp_cookie_text not in self.cookie_status:
- if paintware_minprice_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数1,等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = 1
- else:
- if paintware_minprice_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'需要短信验证,次数{int(self.cookie_status[self.temp_cookie_text]) + 1},等待{float(self.needed_msg_check_pause_time)}秒!')
- self.cookie_status[self.temp_cookie_text] = int(self.cookie_status[self.temp_cookie_text]) + 1
- time.sleep(float(self.needed_msg_check_pause_time))
- # 从self.cookie_text_list获取下一个cookie,因为此cookie需要从list中移除,所以自动就是下一个,如果没有从list中移除,需要+1
- if self.cookie_status[self.temp_cookie_text] >= int(self.needed_msg_check_try_times):
- self.logger_cmd.debug(f'异常{int(self.needed_msg_check_try_times)}次,暂停!')
- temp_cookie_i += 0
- else:
- temp_cookie_i += 1
- else:
- # 其他异常的情况,直接跳出
- # 重置404异常次数
- self.search_goods_404_times = 0
- # 请求成功了,退出循环
- self.search_goods_stop_flag = False
- # 将这个cookie对应的短信验证的次数清0
- self.cookie_status[self.temp_cookie_text] = 0
- break
- # 计算
- self.detail_logger.debug(f"获取商品id:{self.need_check_goods_list[g_i_i]['id']} 磨损区间及最低价信息: {min_price_list}")
- # 区间内容有价格为0,则跳过该商品,跳到下一个商品
- break_flag = False
- for i2 in range(len(min_price_list)):
- if min_price_list[i2]['min_price'] == 0:
- self.detail_logger.debug(f"获取商品id:{self.need_check_goods_list[g_i_i]['id']} 磨损区间及最低价信息中,有价格是0,跳过该商品")
- break_flag = True
- if break_flag:
- self.detail_logger.debug(f"商品id:{self.need_check_goods_list[g_i_i]['id']} 筛选不满足条件,继续下次循环")
- continue
- # 退出条件判断实时判断是否需要退出
- # 3、全区间的最低价 170 * (1+10%),10%是设定的 = 187元
- pd_price = round(round( float(self.goods_min_price) * (100 + float(self.ref_price_adjust)) / 100, 2) + 0.01,2)
- # 4、将5个磨损区间的最低价跟187比对,只留高于这个187价格的区间
- # 遍历 min_price_list
- for i1 in range(len(min_price_list)):
- if min_price_list[i1]['min_price'] < pd_price:
- # min_price_list 删除i1及以后的元素
- min_price_list = min_price_list[:i1]
- break
- # 5、根据阶梯来确定磨损区间
- # 遍历 min_price_list,判断元素中的min_price是否小于上一个元素的min_price,
- for i2 in range(len(min_price_list) - 1):
- if min_price_list[i2]['min_price'] < min_price_list[i2 + 1]['min_price']:
- # min_price_list 删除i2及以后的元素
- min_price_list = min_price_list[:i2 + 1]
- break
- # 6、170*(1+0.02)= 173.4 购买溢价
- gm_price = round(round(float(self.goods_min_price) * (100 + float(self.sweep_price_adjust)) / 100, 2)+ 0.01,2)
- # min_price_list 为空则继续下次循环
- if len(min_price_list) <= 0:
- self.detail_logger.debug(f"商品id:{self.need_check_goods_list[g_i_i]['id']} 筛选不满足条件,继续下次循环")
- continue
- # 向BUFF选品日志标签页中添加一条数据
- timestamp = time.time()
- local_time = time.localtime(timestamp)
- formatted_time = time.strftime('%Y-%m-%d %H:%M:%S', local_time)
- self.detail_logger.debug(f"商品id:{self.need_check_goods_list[g_i_i]['id']} 筛选成功, 及价格区间min_price_list:{min_price_list}")
- # 向BUFF选品日志标签页中增加记录 发出信号而不是直接调用 add_select_log
- self.log_added.emit(str(self.need_check_goods_list[g_i_i]['id']), str(self.need_check_goods_list[g_i_i]["name"]),
- str(min_price_list[0]['min_wear']),
- str(min_price_list[-1]['max_wear']), str(self.goods_min_price), str(gm_price),
- str(pd_price), str(formatted_time))
- conn = sqlite3.connect('buff.db')
- cursor = conn.cursor()
- cursor.execute('''
- INSERT INTO select_logs (item_id, item_name, min_wear, max_wear, min_full_wear_price, sweep_price, judge_price, timestamp)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
- ''', (self.need_check_goods_list[g_i_i]["id"], self.need_check_goods_list[g_i_i]["name"], min_price_list[0]['min_wear'], min_price_list[-1]['max_wear'], self.goods_min_price , gm_price, pd_price, formatted_time))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- # 检索成功数量+1
- self.search_success_count += 1
- if self.temp_cookie_text in self.cookie_status:
- temp_checked_times = self.cookie_status[self.temp_cookie_text]
- else:
- temp_checked_times = 0
- self.xp_logger.debug(f'[已选]正在使用:{self.temp_cookie_text} (已标记{temp_checked_times}次) . 名称:{self.need_check_goods_list[g_i_i]["name"]},ID:{self.need_check_goods_list[g_i_i]["id"]} ,购买底价:{gm_price} , 区间:{min_price_list[0]["min_wear"]}-{min_price_list[-1]["max_wear"]} ')
- self.logger_cmd.debug(f'选品成功。名称:{self.need_check_goods_list[g_i_i]["name"]},ID:{self.need_check_goods_list[g_i_i]["id"]} ,购买底价:{gm_price} , 区间:{min_price_list[0]["min_wear"]}-{min_price_list[-1]["max_wear"]} ')
- except Exception as e:
- self.detail_logger.debug(f"商品id: {self.need_check_goods_list[g_i_i]['id']}判断异常: {e}")
- finally:
- self.searchedGoodsNum += 1
- pass
- except Exception as e:
- self.detail_logger.debug(f"选品接口请求异常: {e}")
- finally:
- self.button_sh.setEnabled(True)
- self.button_stop_sh.setEnabled(True)
- self.button1.setEnabled(True)
- self.detail_logger.debug('停止选品')
- self.logger_cmd.debug('停止选品')
- self.xp_started = False
- # todo 开启扫货
- self.beginSH()
- pass
- # 停止选品
- def stop_selecting(self):
- # 设置选品停止标志为True
- self.stop_selecting_flag = True
- self.xp_started = False
- self.logger_cmd.debug('人工停止选品')
- QMessageBox.information(self, "停止选品", "选品操作已终止")
- # 扫货时候关闭选品 选品时候关闭扫货 todo
- def beginSH(self):
- self.logger_cmd.debug('开始扫货')
- self.detail_logger.debug('开始扫货')
- self.sh_logger.debug('开始扫货')
- # todo 先暂停选品
- self.logger_cmd.debug('暂停选品中')
- self.detail_logger.debug(f'暂停选品中')
- self.sh_logger.debug(f'暂停选品中')
- # 设置扫货停止标志为True
- self.stop_selecting_flag = True
- self.xp_started = False
- time.sleep( float(self.pause_time_edit.text()) )
- # self.button1 self.stop_select_button 按钮不可点击
- self.button1.setEnabled(False)
- self.stop_select_button.setEnabled(False)
- self.button_sh.setEnabled(False)
- self.stop_shopping_flag = False
- # 必填条件,没有则跳出
- # self.sh_phone_number = self.sh_phone_edit.text()
- # QMessageBox.information(self, "扫货手机号码", f"扫货手机号码: {self.sh_phone_number}")
- # # 判断phone_number是否为空,为空则跳出方法
- # if not self.sh_phone_number:
- # QMessageBox.information(self, "扫货手机号码", "扫货手机号码不能为空")
- # return
- # 判断扫货cookie是否为空,为空则退出方法
- self.sh_cookie_text = self.sh_cookie_edit.toPlainText()
- self.detail_logger.debug(f"扫货Cookie: {self.sh_cookie_text}")
- if not self.sh_cookie_text:
- self.detail_logger.debug("扫货Cookie不能为空")
- self.sh_logger.debug("扫货Cookie不能为空")
- return
- # 判断扫货xcsrftoken是否为空,为空则退出方法
- # self.sh_xcsrftoken_text = self.sh_xcsrftoken_edit.toPlainText()
- # self.detail_logger.debug(f"扫货xcsrftoken: {self.sh_xcsrftoken_text}")
- # if not self.sh_xcsrftoken_text:
- # self.detail_logger.debug("扫货xcsrftoken不能为空")
- # return
- try:
- # 获取扫货线程self.shpz_thread_count_edit的值
- self.shpz_thread_count = int(self.shpz_thread_count_edit.text())
- if self.shpz_thread_count > 0 :
- self.detail_logger.debug(f'开启{self.shpz_thread_count}个扫货线程')
- self.sh_logger.debug(f'开启{self.shpz_thread_count}个扫货线程')
- self.logger_cmd.debug(f'开启{self.shpz_thread_count}个扫货线程')
- j = 0
- while j < self.shpz_thread_count:
- j = j + 1
- self.detail_logger.debug(f'开启扫货线程 - {j}')
- thread_BUFFSH = threading.Thread(target=self.BUFFSH,args=(j,))
- thread_BUFFSH.start()
- self.detail_logger.debug(f'开启扫货线程 - {j}完成')
- self.sh_logger.debug(f'开启扫货线程 - {j}完成')
- self.logger_cmd.debug(f'开启扫货线程 - {j}完成')
- except Exception as e:
- # self.button1 self.stop_select_button 按钮不可点击
- self.button1.setEnabled(True)
- self.stop_select_button.setEnabled(True)
- self.button_sh.setEnabled(True)
- self.detail_logger.debug(f"扫货进程开启Error: {e}")
- def BUFFSH(self, thread_num):
- try:
- while True:
- try:
- # logger.debug(f'扫货线程 - {thread_num}')
- if self.stop_shopping_flag:
- self.detail_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.sh_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.logger_cmd.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- return
- # 获取BUFF选品日志标签页列表中的数据
- sh_start_time = 0
- # 间隔扫货
- for i1 in range(self.select_log_tree_widget.topLevelItemCount()):
- if self.stop_shopping_flag:
- self.detail_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.sh_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.logger_cmd.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- return
- #假设为10条数据,三个进程,第1,4,7由第一个进程处理 第2,5,8由第二个进程处理
- if i1 % self.shpz_thread_count == thread_num - 1:
- item = self.select_log_tree_widget.topLevelItem(i1)
- if self.stop_shopping_flag:
- self.detail_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.sh_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.logger_cmd.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- return
- self.sh_logger.debug(f'扫货线程-{thread_num} 名称:{item.text(2)},ID:{item.text(1)} ,购买底价:{item.text(6)} , 区间:{item.text(3)}-{item.text(4)} ')
- goods_id = item.text(1)
- goods_min_wear = item.text(3)
- goods_max_wear = item.text(4)
- goods_buy_price = item.text(6)
- # 请求BUFF 商品信息列表,获取可以购买的商品
- time.sleep(float(self.shpz_pause_time_edit.text()))
- self.logger_cmd.debug(f'扫货线程{thread_num} 名称:{item.text(2)},ID:{item.text(1)} ,购买底价:{item.text(6)} , 区间:{item.text(3)}-{item.text(4)} ')
- self.detail_logger.debug(f'扫货线程-{thread_num} 扫货暂停{float(self.shpz_pause_time_edit.text())}秒')
- # current_time = time.time()
- # time_since_last_request = current_time - sh_start_time
- # if time_since_last_request < float(self.shpz_pause_time_edit.text()):
- # wait_time = float(self.shpz_pause_time_edit.text()) - time_since_last_request
- # self.detail_logger.debug(f"暂停 {wait_time:.2f} seconds before making the next request.")
- # time.sleep(wait_time)
- # logger.debug(f'扫货线程 - {thread_num} 扫货商品id:{goods_id} 磨损区间:{goods_min_wear}-{goods_max_wear} 购买价格:{goods_buy_price}')
- goods_items_list = self.getGoodsInfo(goods_id, goods_min_wear, goods_max_wear, goods_buy_price ,thread_num)
- self.detail_logger.debug(f'扫货线程 - {thread_num} goods_items_list:{goods_items_list}')
- if goods_items_list == 'stop':
- self.detail_logger.debug(f'扫货线程 - {thread_num} 停止扫货')
- self.sh_logger.debug(f'扫货线程 - {thread_num} 停止扫货')
- self.logger_cmd.debug(f'扫货线程{thread_num} 停止扫货')
- return
- self.logger_cmd.debug(f'扫货线程{thread_num} 名称:{item.text(2)},ID:{item.text(1)} ,购买底价:{item.text(6)} , 区间:{item.text(3)}-{item.text(4)}, 共获取到{len(goods_items_list)}个商品可购买 ')
- for goods_item in goods_items_list:
- if self.stop_shopping_flag:
- self.detail_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.sh_logger.debug(f'扫货线程 - {thread_num} 人工停止扫货')
- self.logger_cmd.debug(f'扫货线程{thread_num} 人工停止扫货')
- return
- # post请求购买接口
- try:
- self.detail_logger.debug(f"扫货线程 - {thread_num} 商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']}")
- self.logger_cmd.debug(f"扫货线程{thread_num} 购买 商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']}")
- api_data ={
- "game": "csgo",
- "goods_id": goods_item['goods_id'],
- "sell_order_id": goods_item['id'],
- "price": goods_item['price'],
- "pay_method": 1,
- "allow_tradable_cooldown": 0,
- "token": "",
- "cdkey_id": "",
- "hide_non_epay": False
- }
- api_header = {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
- "Host": "buff.163.com", "X-Requested-With": "XMLHttpRequest",
- 'Referer': f"https://buff.163.com/goods/{goods_item['goods_id']}?from=market",
- 'Cookie': self.sh_cookie_text,
- 'x-csrftoken': self.sh_xcsrftoken_text}
- # todo
- res = req.post(self.sh_buyGoodsUrl, headers=api_header, data=api_data)
- self.detail_logger.debug(f"扫货线程 - {thread_num} 商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']} api_header: {api_header} post-url请求 {self.sh_buyGoodsUrl} 返回报文: {res.text.strip()}")
- self.detail_logger.debug(f'扫货线程 - {thread_num} 购买接口请求返回报文中的CODE:{res.json()["code"]}')
- if res.json()['code'] == 'Captcha Validate Required' or res.json()['code'] == 'Login Required' or res.json()['code'] == 'Action Forbidden':
- self.detail_logger.debug(f'扫货线程 - {thread_num} 购买接口请求返回报文code为Captcha Validate Required 或者 Login Required 或者 Action Forbidden,暂停{self.shpz_need_check_time_edit.text()}秒后重试')
- retry_count = 0
- while retry_count < int(self.shpz_need_try_time_edit.text()):
- self.detail_logger.debug(f'扫货线程 - {thread_num} 购买接口请求返回报文code为Captcha Validate Required,第{retry_count + 1}次重试')
- time.sleep(float(self.shpz_need_check_time_edit.text()))
- res = req.post(self.sh_buyGoodsUrl, headers=api_header, data=api_data)
- # data = api1_res.json()['data']
- if res.json()['code'] == 'System Error':
- # self.logger_cmd.debug(f"扫货线程{thread_num} 访问频繁")
- continue
- if res.json()['code'] == 'OK':
- self.logger_cmd.debug(f"扫货线程{thread_num} 购买成功 商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']}")
- break
- if res.json()['code'] == 'Captcha Validate Required' or res.json()['code'] == 'Login Required' or res.json()['code'] == 'Action Forbidden':
- retry_count += 1
- if res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'扫货线程{thread_num} 需要短信验证,次数{retry_count},等待{float(self.shpz_need_check_time_edit.text())}秒!')
- if res.json()['code'] == 'Login Required':
- self.logger_cmd.debug(f'扫货线程{thread_num} 需要登陆,次数{retry_count},等待{float(self.shpz_need_check_time_edit.text())}秒!')
- if res.json()['code'] == 'Captcha Validate Required' or res.json()['code'] == 'Login Required' or res.json()['code'] == 'Action Forbidden':
- self.detail_logger.debug(f'扫货线程 - {thread_num} 选品获取商品信息接口请求返回报文code仍然为Captcha Validate Required 或者 Login Required 或者 Action Forbidden,跳出循环')
- self.logger_cmd.debug(f'扫货线程{thread_num} 异常{int(self.shpz_need_try_time_edit.text())}次,暂停!')
- return
- elif res.json()['code'] != 'OK':
- # 如果data中的code不等于OK,则跳出循环
- self.detail_logger.debug(f'扫货线程 - {thread_num} 选品接口请求返回报文: {res.text.strip()[:50]}')
- self.detail_logger.debug(f'扫货线程 - {thread_num} 选品接口请求返回报文code不等于OK,跳出循环')
- continue
- if res.json()['code'] == 'OK':
- self.detail_logger.debug(f"扫货线程 - {thread_num} ,商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']} 购买成功")
- self.gm_logger.debug(f"名称:{item.text(2)},ID:{goods_item['goods_id']} ,购买底价:{item.text(6)} , 区间:{item.text(3)}-{item.text(4)} 购买价格:{goods_item['price']}")
- except Exception as e:
- self.detail_logger.debug(f"扫货线程 - {thread_num} 商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']} 购买商品信息接口请求--失败: {e}")
- finally:
- sh_start_time = time.time()
- # # 结束时间为当前时间
- # end_time = time.time()
- # # 从start_time到end_time 必须修改pause_time秒
- # if float(end_time - start_time) < float(self.pause_time_edit.text()):
- # time.sleep(float(self.pause_time_edit.text()) - (end_time - start_time) + random.randint(0, 5))
- except Exception as e:
- self.detail_logger.debug(f'扫货线程 - {thread_num} 购买商品信息接口请求--失败:{e}')
- finally:
- pass
- finally:
- self.button1.setEnabled(True)
- self.stop_select_button.setEnabled(True)
- self.button_sh.setEnabled(True)
- self.sh_logger.debug(f'扫货线程 - {thread_num} 停止扫货')
- self.detail_logger.debug(f'扫货线程 - {thread_num} 停止扫货')
- self.logger_cmd.debug(f'扫货线程{thread_num} 停止扫货')
- def getGoodsInfo(self, goods_id, goods_min_wear, goods_max_wear, goods_buy_price,thread_num):
- # # 获取当前时间戳
- # timestamp = time.time()
- # # 将时间戳转换为datetime对象
- # dt_object = datetime.fromtimestamp(timestamp)
- self.detail_logger.debug(f"扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息")
- self.logger_cmd.debug(f"扫货线程{thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息")
- # 开始时间为当前时间
- goods_id_list = []
- start_time = time.time()
- self.sh_my_headers.update({
- 'Cookie': self.sh_cookie_text
- })
- try:
- # todo 为了测试,先去除磨损区间
- api_url = f'{self.sh_getToBuyUrl}{goods_id}&min_price=0&max_price={goods_buy_price}&min_paintwear={goods_min_wear}&max_paintwear={goods_max_wear}'
- #api_url = f'{self.sh_getToBuyUrl}{goods_id}&min_price=0&max_price={goods_buy_price}'
- self.detail_logger.debug(f'扫货线程 - {thread_num} api_url = {api_url}')
- api2_res = req.get(api_url, headers=self.sh_my_headers)
- # logger.debug(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息的返回报文: {api2_res.text.strip()}')
- if api2_res.json()['code'] == 'Captcha Validate Required' or api2_res.json()['code'] == 'Login Required' or api2_res.json()['code'] == 'Action Forbidden':
- self.detail_logger.debug(f'扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息的返回报文code为Captcha Validate Required 或者 Login Required 或者 Action Forbidden ,暂停{self.shpz_need_check_time_edit.text()}秒后重试')
- retry_count = 0
- while retry_count < int(self.shpz_need_try_time_edit.text()):
- self.detail_logger.debug(f'扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息请求返回报文code为Captcha Validate Required,第{retry_count + 1}次重试')
- time.sleep(float(self.shpz_need_check_time_edit.text()))
- api2_res = req.get(api_url, headers=self.sh_my_headers)
- # data = api1_res.json()['data']
- if api2_res.json()['code'] == 'System Error':
- # time.sleep(30)
- # self.logger_cmd.debug(f'扫货线程{thread_num} 返回码:System Error 访问频繁 ')
- continue
- if api2_res.json()['code'] == 'OK':
- break
- if api2_res.json()['code'] == 'Captcha Validate Required' or api2_res.json()['code'] == 'Login Required' or api2_res.json()['code'] == 'Action Forbidden':
- retry_count += 1
- if api2_res.json()['code'] == 'Captcha Validate Required':
- self.logger_cmd.debug(f'扫货线程{thread_num} 需要短信验证,次数{retry_count},等待{float(self.shpz_need_check_time_edit.text())}秒!')
- if api2_res.json()['code'] == 'Login Required':
- self.logger_cmd.debug(f'扫货线程{thread_num} 需要登陆,次数{retry_count},等待{float(self.shpz_need_check_time_edit.text())}秒!')
- if api2_res.json()['code'] == 'Captcha Validate Required' or api2_res.json()['code'] == 'Login Required' or api2_res.json()['code'] == 'Action Forbidden':
- self.detail_logger.debug(f'扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息请求返回报文code仍然为Captcha Validate Required 或者 Login Required 或者 Action Forbidden,跳出循环')
- goods_id_list = 'stop'
- self.logger_cmd.debug(f'扫货线程{thread_num} 异常{int(self.shpz_need_try_time_edit.text())}次,暂停!')
- return 'stop'
- elif api2_res.json()['code'] != 'OK':
- # self.logger_cmd.debug(f'扫货线程{thread_num} 请求异常 ')
- self.detail_logger.debug(f'扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息请求返回报文: {api2_res.text.strip()}')
- self.detail_logger.debug(f'扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息接口请求返回报文code不等于OK,跳出循环')
- return goods_id_list
- if api2_res.json()['code'] == 'OK':
- data = api2_res.json()['data']
- goods_id_list = data['items']
- # 获取响应的header信息
- headers = api2_res.headers
- self.detail_logger.debug(f'headers: {headers}')
- # 打印header信息
- for header, value in headers.items():
- # 获取set-cookie中 csrf_token的值
- if header == 'set-cookie':
- cookies_list = value.split(', ')
- # print(f'cookies_list: {cookies_list}')
- for cookie in cookies_list:
- if 'csrf_token' in cookie:
- csrf_token = cookie.split('=')[1].split(';')[0]
- self.sh_xcsrftoken_text = csrf_token
- self.detail_logger.debug(f"扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息: {goods_id_list}")
- except Exception as e:
- self.detail_logger.debug(f'扫货线程 - {thread_num} 获取商品id: {goods_id} 的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息接口请求--失败:{e}')
- finally:
- # # # 结束时间为当前时间
- # end_time = time.time()
- # # 从start_time到end_time 必须修改pause_time秒
- # if float(end_time - start_time) < float(self.pause_time_edit.text()):
- # time.sleep(float(self.pause_time_edit.text()) - (end_time - start_time) )
- return goods_id_list
- def stopSH(self):
- # 在这里添加停止扫货的逻辑
- # 设置扫货停止标志为True
- self.stop_shopping_flag = True
- QMessageBox.information(self, "停止扫货", "扫货操作已终止")
- # 选品账号信息tab页加载
- def create_account_info_form(self, prefix):
- form_layout = QFormLayout()
- # 从sqlite中accounts获取信息,降数据库中得到值填到输入框中
- # 从数据库中获取默认值
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT phone_number, email, email_alias, cookie FROM accounts LIMIT 1")
- default_values = c.fetchone()
- conn.close()
- # 设置默认值
- # phone_default = default_values[0] if default_values else "17756576757"
- # email_default = default_values[1] if default_values else "704541015@qq.com"
- # code_default = default_values[2] if default_values else "0012312"
- cookie_default = default_values[3] if default_values else ""
- # 创建输入框及其标签
- # phone_label = QLabel(f"{prefix}手机号码")
- # phone_edit = QLineEdit()
- # phone_edit.setFixedWidth(300) # 设置固定宽度为500像素
- # phone_edit.setText(phone_default) # 设置选品手机号码默认值
- # form_layout.addRow(phone_label, phone_edit)
- # email_label = QLabel(f"{prefix}邮箱号")
- # email_edit = QLineEdit()
- # email_edit.setFixedWidth(300) # 设置固定宽度为500像素
- # email_edit.setText(email_default) # 设置选品邮箱号默认值
- # form_layout.addRow(email_label, email_edit)
- # email_alias_label = QLabel(f"{prefix}邮箱特殊代码")
- # email_alias_edit = QLineEdit()
- # email_alias_edit.setFixedWidth(300) # 设置固定宽度为500像素
- # email_alias_edit.setText(code_default) # 设置选品邮箱特殊代码默认值
- # form_layout.addRow(email_alias_label, email_alias_edit)
- cookie_label = QLabel(f"{prefix}cookie")
- self.xp_cookie_edit = QTextEdit() # 使用QTextEdit代替QLineEdit
- self.xp_cookie_edit.setFixedWidth(400) # 设置固定宽度为500像素
- self.xp_cookie_edit.setText(cookie_default) # 设置选品cookie默认值
- form_layout.addRow(cookie_label, self.xp_cookie_edit)
- # 保存输入框的引用以便后续访问
- # self.phone_edit_map[prefix] = phone_edit
- # self.email_edit_map[prefix] = email_edit
- # self.email_alias_edit_map[prefix] = email_alias_edit
- # 添加保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_account_info)
- save_button.setFixedSize(100, 50) # 设置固定宽度为500像素
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(10, 0, 0, 0)
- button_layout.addWidget(save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(10, 0, 0, 0)
- return form_layout
- # 选品账号信息保存按钮功能
- def save_account_info(self):
- # phone_number = self.phone_edit_map["选品"].text()
- # # 获取选品邮箱号
- # email = self.email_edit_map["选品"].text()
- # email_alias = self.email_alias_edit_map["选品"].text()
- cookie = self.xp_cookie_edit.toPlainText()
- # if not phone_number or not email or not email_alias or not cookie:
- if not cookie:
- QMessageBox.warning(self, "保存账号信息", "所有字段都必须填写")
- return
- try:
- conn = sqlite3.connect('buff.db')
- cursor = conn.cursor()
- cursor.execute('delete from accounts ')
- cursor.execute('''
- INSERT INTO accounts (phone_number, email, email_alias, cookie)
- VALUES (?, ?, ?, ?)
- ''', ('1','1','1', cookie))
- conn.commit()
- conn.close()
- QMessageBox.information(self, "保存账号信息", "账号信息已成功保存")
- except Exception as e:
- QMessageBox.critical(self, "保存账号信息", f"保存账号信息时发生错误: {e}")
- # 品类信息tab页加载
- def create_category_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.tree_widget = QTreeWidget()
- self.tree_widget.setHeaderLabels(["选择", "品类名称", "品类编码"])
- self.tree_widget.setColumnCount(3)
- self.tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.tree_widget.setColumnWidth(0, 100) # 设置选择列的宽度
- self.tree_widget.setColumnWidth(1, 100) # 设置品类名称列的宽度
- self.tree_widget.setColumnWidth(2, 100) # 设置品类编码列的宽度
- self.tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "品类名称", "品类编码"])) # 设置表头
- self.tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的品类信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM categories ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.tree_widget)
- item.setText(1, row[0])
- item.setText(2, row[1])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_category)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_category)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_category)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_categories)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 新增品类信息
- def add_category(self):
- CategoryDialog.add_category(self)
- # 删除品类信息
- def delete_category(self):
- CategoryDialog.delete_category(self)
- # 编辑品类信息
- def edit_category(self):
- CategoryDialog.edit_category(self)
- # 保存品类信息
- def save_categories(self):
- CategoryDialog.save_categories(self)
- # 品质信息tab页加载
- def create_quality_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.quality_tree_widget = QTreeWidget()
- self.quality_tree_widget.setHeaderLabels(["选择", "品质编码", "品质名称"])
- self.quality_tree_widget.setColumnCount(3)
- self.quality_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.quality_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.quality_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.quality_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.quality_tree_widget.setColumnWidth(0, 100) # 设置选择列的宽度
- self.quality_tree_widget.setColumnWidth(1, 100) # 设置品质编码列的宽度
- self.quality_tree_widget.setColumnWidth(2, 100) # 设置品质名称列的宽度
- self.quality_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "品质编码", "品质名称"])) # 设置表头
- self.quality_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的品质信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM qualities ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.quality_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.quality_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.quality_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_quality)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_quality)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_quality)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_qualities)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 新增品质信息
- def add_quality(self):
- QualityDialog.add_quality(self)
- # 删除品质信息
- def delete_quality(self):
- QualityDialog.delete_quality(self)
- # 编辑品质信息
- def edit_quality(self):
- QualityDialog.edit_quality(self)
- # 保存品质信息
- def save_qualities(self):
- QualityDialog.save_qualities(self)
- # 加载类别信息tab页
- def create_type_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.type_tree_widget = QTreeWidget()
- self.type_tree_widget.setHeaderLabels(["选择", "type编码", "type名称"])
- self.type_tree_widget.setColumnCount(3)
- self.type_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.type_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.type_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.type_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.type_tree_widget.setColumnWidth(0, 100) # 设置选择列的宽度
- self.type_tree_widget.setColumnWidth(1, 100) # 设置type编码列的宽度
- self.type_tree_widget.setColumnWidth(2, 100) # 设置type名称列的宽度
- self.type_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "type编码", "type名称"])) # 设置表头
- self.type_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的type信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM types ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.type_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.type_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.type_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_type)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_type)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_type)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_types)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 新增类别信息
- def add_type(self):
- TypeDialog.add_type(self)
- # 删除类别信息
- def delete_type(self):
- TypeDialog.delete_type(self)
- # 编辑类别信息
- def edit_type(self):
- TypeDialog.edit_type(self)
- # 保存类别信息
- def save_types(self):
- TypeDialog.save_types(self)
- # 加载外观信息tab页
- def create_appearance_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.appearance_tree_widget = QTreeWidget()
- self.appearance_tree_widget.setHeaderLabels(["选择", "外观编码", "外观名称"])
- self.appearance_tree_widget.setColumnCount(3)
- self.appearance_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.appearance_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.appearance_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.appearance_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.appearance_tree_widget.setColumnWidth(0, 100) # 设置选择列的宽度
- self.appearance_tree_widget.setColumnWidth(1, 100) # 设置外观编码列的宽度
- self.appearance_tree_widget.setColumnWidth(2, 100) # 设置外观名称列的宽度
- self.appearance_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "外观编码", "外观名称"])) # 设置表头
- self.appearance_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的外观信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM appearances ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.appearance_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.appearance_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.appearance_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_appearance)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_appearance)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_appearance)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_appearances)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 新增外观信息
- def add_appearance(self):
- AppearanceDialog.add_appearance(self)
- # 删除外观信息
- def delete_appearance(self):
- AppearanceDialog.delete_appearance(self)
- # 编辑外观信息
- def edit_appearance(self):
- AppearanceDialog.edit_appearance(self)
- # 保存外观信息
- def save_appearances(self):
- AppearanceDialog.save_appearances(self)
- # 加载收藏品信息tab页
- def create_collectible_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.collectible_tree_widget = QTreeWidget()
- self.collectible_tree_widget.setHeaderLabels(["选择", "收藏品编码", "收藏品名称"])
- self.collectible_tree_widget.setColumnCount(3)
- self.collectible_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.collectible_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.collectible_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.collectible_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.collectible_tree_widget.setColumnWidth(0, 100) # 设置选择列的宽度
- self.collectible_tree_widget.setColumnWidth(1, 100) # 设置收藏品编码列的宽度
- self.collectible_tree_widget.setColumnWidth(2, 100) # 设置收藏品名称列的宽度
- self.collectible_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "收藏品编码", "收藏品名称"])) # 设置表头
- self.collectible_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的收藏品信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM collectibles ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.collectible_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.collectible_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.collectible_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_collectible)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_collectible)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_collectible)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_collectibles)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 新增收藏品
- def add_collectible(self):
- CollectibleDialog.add_collectible(self)
- # 删除收藏品
- def delete_collectible(self):
- CollectibleDialog.delete_collectible(self)
- # 编辑收藏品
- def edit_collectible(self):
- CollectibleDialog.edit_collectible(self)
- # 保存收藏品
- def save_collectibles(self):
- CollectibleDialog.save_collectibles(self)
- # 加载选品配置信息tab页
- def create_config_info_form(self, prefix):
- form_layout = QFormLayout()
- form_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保表单布局内容靠左对齐
- # 从数据库中获取默认值
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute(
- "SELECT min_price, max_price, sort_mode, stop_condition, "
- "success_count, scan_count, page_size, pause_time, max_pages, "
- "ref_price_adjust, sweep_price_adjust,needed_msg_check_pause_time ,"
- "needed_msg_check_try_times,delete_ids,cron_time,sell_num FROM config LIMIT 1")
- default_values = c.fetchone()
- conn.close()
- # 创建选品最低价输入框及其标签
- min_price_label = QLabel(f"{prefix}最低价")
- self.min_price_edit = QLineEdit()
- self.min_price_edit.setFixedWidth(300) # 设置固定宽度为500像素
- # default_values 为None
- if default_values is not None:
- self.min_price_edit.setText(str(default_values[0]))
- form_layout.addRow(min_price_label, self.min_price_edit)
- # 创建选品最高价输入框及其标签
- max_price_label = QLabel(f"{prefix}最高价")
- self.max_price_edit = QLineEdit()
- self.max_price_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.max_price_edit.setText(str(default_values[1]))
- form_layout.addRow(max_price_label, self.max_price_edit)
- # 创建选品排序模式下拉选择框及其标签
- sort_mode_label = QLabel(f"{prefix}排序模式")
- self.sort_mode_combo = QComboBox()
- self.sort_mode_combo.addItems(["默认", "价格升序", "价格降序", "在售数量升序"])
- self.sort_mode_combo.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.sort_mode_combo.setCurrentText(default_values[2])
- form_layout.addRow(sort_mode_label, self.sort_mode_combo)
- # 创建选品停止条件下拉选择框及其标签
- stop_condition_label = QLabel(f"{prefix}停止条件")
- self.stop_condition_combo = QComboBox()
- self.stop_condition_combo.addItems(["按照成功数量", "按照扫描数量"])
- self.stop_condition_combo.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.stop_condition_combo.setCurrentText(default_values[3])
- form_layout.addRow(stop_condition_label, self.stop_condition_combo)
- # 创建成功数量配置输入框及其标签
- success_count_label = QLabel(f"{prefix}成功数量配置")
- self.success_count_edit = QLineEdit()
- self.success_count_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.success_count_edit.setText(str(default_values[4]))
- form_layout.addRow(success_count_label, self.success_count_edit)
- # 创建扫描商品数量配置输入框及其标签
- scan_count_label = QLabel(f"{prefix}扫描商品数量")
- self.scan_count_edit = QLineEdit()
- self.scan_count_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.scan_count_edit.setText(str(default_values[5]))
- form_layout.addRow(scan_count_label, self.scan_count_edit)
- # 创建选品接口每页请求数量配置输入框及其标签
- page_size_label = QLabel(f"{prefix}接口每页请求数量")
- self.page_size_edit = QLineEdit()
- self.page_size_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.page_size_edit.setText(str(default_values[6]))
- form_layout.addRow(page_size_label, self.page_size_edit)
- # 创建每次调用BUFF接口暂停时间配置输入框及其标签
- pause_time_label = QLabel(f"{prefix}接口暂停时间(秒)")
- self.pause_time_edit = QLineEdit()
- self.pause_time_edit.setFixedWidth(300) # 设置固定宽度为500像素
- # self.pause_time_edit.setText("10") # 设置默认值为10
- if default_values is not None:
- self.pause_time_edit.setText(str(default_values[7]))
- form_layout.addRow(pause_time_label, self.pause_time_edit)
- # 创建选品接口最大请求多少页配置输入框及其标签
- max_pages_label = QLabel(f"{prefix}接口最大请求多少页")
- self.max_pages_edit = QLineEdit()
- self.max_pages_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.max_pages_edit.setText(str(default_values[8]))
- form_layout.addRow(max_pages_label, self.max_pages_edit)
- # 创建商品参考价调整系数输入框及其标签
- ref_price_adjust_label = QLabel(f"{prefix}商品参考价调整系数%")
- self.ref_price_adjust_edit = QLineEdit()
- self.ref_price_adjust_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.ref_price_adjust_edit.setText(str(default_values[9]))
- form_layout.addRow(ref_price_adjust_label, self.ref_price_adjust_edit)
- # 创建商品扫货价调整系数输入框及其标签
- sweep_price_adjust_label = QLabel(f"{prefix}商品扫货价调整系数%")
- self.sweep_price_adjust_edit = QLineEdit()
- self.sweep_price_adjust_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.sweep_price_adjust_edit.setText(str(default_values[10]))
- form_layout.addRow(sweep_price_adjust_label, self.sweep_price_adjust_edit)
- # 商品选品弹出需要短信验证时,下次请求暂停时长,默认为0
- needed_msg_check_pause_time_label = QLabel(f"{prefix}API接口需短信验证时\n下次选品暂停时长(秒)")
- self.needed_msg_check_pause_time_edit = QLineEdit()
- self.needed_msg_check_pause_time_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.needed_msg_check_pause_time_edit.setText(str(default_values[11]))
- form_layout.addRow(needed_msg_check_pause_time_label, self.needed_msg_check_pause_time_edit)
- #商品选品弹出需要短信验证时 尝试几次后仍异常,退出选品
- needed_msg_check_try_times_label = QLabel(f"{prefix}API接口需短信验证时\n尝试几次后仍异常,退出选品(次)")
- self.needed_msg_check_try_times_edit = QLineEdit()
- self.needed_msg_check_try_times_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.needed_msg_check_try_times_edit.setText(str(default_values[12]))
- form_layout.addRow(needed_msg_check_try_times_label, self.needed_msg_check_try_times_edit)
- # 需剔除的id列表
- delete_ids_label = QLabel(f"需剔除的id列表(#号分割)")
- self.delete_ids_label_edit = QLineEdit()
- self.delete_ids_label_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.delete_ids_label_edit.setText(str(default_values[13]))
- form_layout.addRow(delete_ids_label, self.delete_ids_label_edit)
- # 每天定时执行时间的配置
- cron_time_label = QLabel(f"每天定时执行时间的配置(9代表9点)")
- self.cron_time_label_edit = QLineEdit()
- self.cron_time_label_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.cron_time_label_edit.setText(str(default_values[14]))
- form_layout.addRow(cron_time_label, self.cron_time_label_edit)
- # 销售数量的配置
- sell_num_label = QLabel(f"销售数量配置")
- self.sell_num_label_edit = QLineEdit()
- self.sell_num_label_edit.setFixedWidth(300) # 设置固定宽度为500像素
- if default_values is not None:
- self.sell_num_label_edit.setText(str(default_values[15]))
- form_layout.addRow(sell_num_label, self.sell_num_label_edit)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_config)
- save_button.setFixedSize(100, 50) # 设置固定宽度为500像素
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(10, 0, 0, 0)
- button_layout.addWidget(save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(10, 0, 0, 0)
- return form_layout
- # 保存选品配置信息
- def save_config(self):
- # 连接到SQLite数据库
- conn = sqlite3.connect('buff.db')
- cursor = conn.cursor()
- # 清空表中的数据
- cursor.execute('DELETE FROM config')
- # 获取配置信息
- min_price = self.min_price_edit.text()
- max_price = self.max_price_edit.text()
- sort_mode = self.sort_mode_combo.currentText()
- stop_condition = self.stop_condition_combo.currentText()
- success_count = self.success_count_edit.text()
- scan_count = self.scan_count_edit.text()
- page_size = self.page_size_edit.text()
- pause_time = self.pause_time_edit.text()
- max_pages = self.max_pages_edit.text()
- ref_price_adjust = self.ref_price_adjust_edit.text()
- sweep_price_adjust = self.sweep_price_adjust_edit.text()
- needed_msg_check_pause_time = self.needed_msg_check_pause_time_edit.text()
- needed_msg_check_try_times = self.needed_msg_check_try_times_edit.text()
- delete_ids = self.delete_ids_label_edit.text()
- cron_time = self.cron_time_label_edit.text()
- sell_num = self.sell_num_label_edit.text()
- # 插入数据到表中
- cursor.execute('''
- INSERT INTO config (min_price, max_price, sort_mode, stop_condition, success_count, scan_count, page_size, pause_time, max_pages, ref_price_adjust, sweep_price_adjust,needed_msg_check_pause_time,needed_msg_check_try_times,delete_ids,cron_time,sell_num)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?)
- ''', (
- min_price, max_price, sort_mode, stop_condition, success_count, scan_count, page_size, pause_time,
- max_pages,
- ref_price_adjust, sweep_price_adjust,needed_msg_check_pause_time,needed_msg_check_try_times,delete_ids,cron_time,sell_num))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- QMessageBox.information(self, "保存选品配置", "选品配置已成功保存")
- # 加载选品日志的tab框
- def create_select_log_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.select_log_tree_widget = QTreeWidget()
- self.select_log_tree_widget.setHeaderLabels(
- ["选择", "商品ID", "商品名称", "磨损最低值", "磨损最高值", "全磨损区间最低价", "扫货价", "判断价", "时间"])
- self.select_log_tree_widget.setColumnCount(9)
- self.select_log_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.select_log_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.select_log_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.select_log_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.select_log_tree_widget.setColumnWidth(0, 50) # 设置选择列的宽度
- self.select_log_tree_widget.setColumnWidth(1, 50) # 设置商品ID列的宽度
- self.select_log_tree_widget.setColumnWidth(2, 50) # 设置商品名称列的宽度
- self.select_log_tree_widget.setColumnWidth(3, 50) # 设置磨损最低值列的宽度
- self.select_log_tree_widget.setColumnWidth(4, 50) # 设置磨损最高值列的宽度
- self.select_log_tree_widget.setColumnWidth(5, 50) # 设置全磨损区间最低价列的宽度
- self.select_log_tree_widget.setColumnWidth(6, 50) # 设置扫货价列的宽度
- self.select_log_tree_widget.setColumnWidth(7, 50) # 设置判断价列的宽度
- self.select_log_tree_widget.setColumnWidth(8, 50) # 设置时间列的宽度
- self.select_log_tree_widget.setHeaderItem(QTreeWidgetItem(
- ["序号", "商品ID", "商品名称", "磨损最低值", "磨损最高值", "全磨损区间最低价", "扫货价", "判断价",
- "时间"])) # 设置表头
- self.select_log_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute(
- "SELECT item_id, item_name, min_wear, max_wear, min_full_wear_price, sweep_price, judge_price, timestamp FROM select_logs ")
- rows = c.fetchall()
- item_i = 1
- for row in rows:
- item = QTreeWidgetItem(self.select_log_tree_widget)
- item.setText(0, str(item_i))
- item.setText(1, str(row[0]))
- item.setText(2, str(row[1]))
- item.setText(3, str(row[2]))
- item.setText(4, str(row[3]))
- item.setText(5, str(row[4]))
- item.setText(6, str(row[5]))
- item.setText(7, str(row[6]))
- item.setText(8, str(row[7]))
- item_i += 1
- # checkbox = QCheckBox()
- # checkbox.setChecked(False)
- # self.select_log_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.select_log_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.show_add_select_log_dialog)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_select_log)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_select_log)
- button_layout.addWidget(edit_button)
- # 创建导出按钮
- export_button = QPushButton("导出")
- export_button.clicked.connect(self.export_selected_logs)
- button_layout.addWidget(export_button)
- # 创建导入按钮
- import_button = QPushButton("导入")
- import_button.clicked.connect(self.import_selected_logs)
- button_layout.addWidget(import_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_select_logs)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 导入日志
- def import_selected_logs(self):
- # 导入元素的逻辑
- file_path, _ = QFileDialog.getOpenFileName(self, "导入商品数据", "", "JSON Files (*.json);;All Files (*)")
- if file_path:
- with open(file_path, 'r', encoding='utf-8') as f:
- items = json.load(f)
- for item_id, item_data in items.items():
- item = QTreeWidgetItem()
- item.setText(0, "") # 商品选择
- item.setText(1, item_data['商品ID'])
- item.setText(2, item_data['商品名称'])
- item.setText(3, item_data['磨损最低值'])
- item.setText(4, item_data['磨损最高值'])
- item.setText(5, item_data['全磨损区间最低价'])
- item.setText(6, item_data['扫货价'])
- item.setText(7, item_data['判断价'])
- item.setText(8, item_data['时间'])
- self.select_log_tree_widget.addTopLevelItem(item)
- SelectLogDialog.update_row_numbers(self)
- self.save_select_logs()
- QMessageBox.information(self, "成功", "数据已成功导入")
- # 导出日志
- def export_selected_logs(self):
- SelectLogDialog.export_selected_logs(self)
- # 保存日志
- def save_select_logs(self):
- SelectLogDialog.save_select_logs(self)
- # 编辑日志
- def edit_select_log(self):
- SelectLogDialog.edit_select_log(self)
- # 删除日志
- def delete_select_log(self):
- SelectLogDialog.delete_select_log(self)
- # 新增日志
- def show_add_select_log_dialog(self):
- SelectLogDialog.show_add_select_log_dialog(self)
- # 加载扫货账号信息tab页
- def setup_shzhtab(self):
- # 创建表单布局
- form_layout = QFormLayout()
- # 从数据库中获取默认值
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT phone, email, code, cookie,xcsrftoken FROM sh_account_info LIMIT 1")
- default_values = c.fetchone()
- conn.close()
- # 设置默认值
- phone_default = default_values[0] if default_values else "17756576757"
- email_default = default_values[1] if default_values else "704541015@qq.com"
- code_default = default_values[2] if default_values else "0012312"
- cookie_default = default_values[3] if default_values else ""
- xcsrftoken_default = default_values[4] if default_values else ""
- # 添加输入字段
- self.sh_phone_edit = QLineEdit(phone_default)
- self.sh_email_edit = QLineEdit(email_default)
- self.sh_code_edit = QLineEdit(code_default)
- self.sh_cookie_edit = QTextEdit(cookie_default)
- self.sh_xcsrftoken_edit = QTextEdit(xcsrftoken_default)
- # 设置输入字段的宽度
- self.sh_phone_edit.setFixedWidth(300)
- self.sh_email_edit.setFixedWidth(300)
- self.sh_code_edit.setFixedWidth(300)
- self.sh_cookie_edit.setFixedWidth(300)
- self.sh_xcsrftoken_edit.setFixedWidth(300)
- form_layout.addRow("扫货手机号码", self.sh_phone_edit)
- form_layout.addRow("扫货邮箱号", self.sh_email_edit)
- form_layout.addRow("扫货邮箱特殊代码", self.sh_code_edit)
- form_layout.addRow("扫货cookie", self.sh_cookie_edit)
- form_layout.addRow("扫货xcsrftoken", self.sh_xcsrftoken_edit)
- # 创建主布局
- main_layout = QVBoxLayout()
- main_layout.addLayout(form_layout)
- # 连接保存按钮信号和槽
- self.sh_save_button = QPushButton("保存")
- self.sh_save_button.clicked.connect(self.save_sh_account_info)
- self.sh_save_button.setFixedSize(100, 50)
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(10, 0, 0, 0)
- button_layout.addWidget(self.sh_save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(10, 0, 0, 0)
- return main_layout
- # 保存扫货账号信息
- def save_sh_account_info(self):
- import sqlite3
- # 连接到SQLite数据库(如果数据库不存在,则会自动创建)
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute('DELETE FROM sh_account_info')
- # 插入数据
- c.execute("INSERT INTO sh_account_info (phone, email, code, cookie,xcsrftoken) VALUES (?, ?, ?, ?,?)",
- (self.sh_phone_edit.text(), self.sh_email_edit.text(), self.sh_code_edit.text(),
- self.sh_cookie_edit.toPlainText(), self.sh_xcsrftoken_edit.toPlainText()))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- QMessageBox.information(self, "成功", "扫货账号信息已保存")
- # 加载扫货配置tab页信息
- def setup_shpztab(self):
- # 创建表单布局
- form_layout = QFormLayout()
- # 添加输入字段
- self.shpz_pause_time_edit = QLineEdit()
- self.shpz_pause_time_edit.setFixedWidth(150)
- form_layout.addRow("API接口请求暂停时间(秒)", self.shpz_pause_time_edit)
- # 添加扫货线程数输入字段
- self.shpz_thread_count_edit = QLineEdit()
- self.shpz_thread_count_edit.setFixedWidth(150)
- form_layout.addRow("扫货线程数", self.shpz_thread_count_edit)
- # 添加扫货API接口需短信验证时,下次扫货暂停时长(秒)
- self.shpz_need_check_time_edit = QLineEdit()
- self.shpz_need_check_time_edit.setFixedWidth(150)
- form_layout.addRow("扫货API接口需短信验证时,\n 下次扫货暂停时长(秒)", self.shpz_need_check_time_edit)
- # 添加扫货API接口需短信验证时,尝试几次后仍异常,退出扫货(次)
- self.shpz_need_try_time_edit = QLineEdit()
- self.shpz_need_try_time_edit.setFixedWidth(150)
- form_layout.addRow("扫货API接口需短信验证时,\n 尝试几次后仍异常,退出扫货(次)", self.shpz_need_try_time_edit)
- # 创建主布局
- main_layout = QVBoxLayout()
- main_layout.addLayout(form_layout)
- # 创建保存按钮
- self.shpz_save_button = QPushButton("保存")
- self.shpz_save_button.clicked.connect(self.shpz_save_settings)
- self.shpz_save_button.setFixedSize(100, 50)
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(10, 0, 0, 0)
- button_layout.addWidget(self.shpz_save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(10, 0, 0, 0)
- # 添加pause_time_edit到主布局
- main_layout.addWidget(self.shpz_pause_time_edit)
- main_layout.addWidget(self.shpz_thread_count_edit)
- main_layout.addWidget(self.shpz_need_check_time_edit)
- main_layout.addWidget(self.shpz_need_try_time_edit)
- # 加载默认值
- self.load_shpz_settings_from_db()
- return main_layout
- # 保存扫货配置信息
- def shpz_save_settings(self):
- import sqlite3
- # 连接到SQLite数据库(如果数据库不存在,则会自动创建)
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute('DELETE FROM shpz_settings')
- # 插入数据
- c.execute("INSERT INTO shpz_settings (pause_time, thread_count,needed_msg_check_pause_time ,needed_msg_check_try_times ) VALUES (?, ?,?,?)",
- (float(self.shpz_pause_time_edit.text()), int(self.shpz_thread_count_edit.text()),int(self.shpz_need_check_time_edit.text()),int(self.shpz_need_try_time_edit.text())))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- QMessageBox.information(self, "成功", "设置已保存")
- # 从数据库读取扫货配置信息
- def load_shpz_settings_from_db(self):
- import sqlite3
- # 连接到SQLite数据库
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- # 查询数据
- c.execute("SELECT pause_time, thread_count,needed_msg_check_pause_time ,needed_msg_check_try_times FROM shpz_settings LIMIT 1")
- default_value = c.fetchone()
- # 设置默认值
- pause_time_default = default_value[0] if default_value else "5"
- thread_count_default = default_value[1] if default_value else "1" # 默认扫货线程数为1
- needed_msg_check_pause_time = default_value[2] if default_value else "1" # 默认扫货线程数为1
- needed_msg_check_try_times = default_value[3] if default_value else "1" # 默认扫货线程数为1
- # 设置输入字段的默认值
- self.shpz_pause_time_edit.setText(str(pause_time_default))
- self.shpz_thread_count_edit.setText(str(thread_count_default))
- self.shpz_need_check_time_edit.setText(str(needed_msg_check_pause_time))
- self.shpz_need_try_time_edit.setText(str(needed_msg_check_try_times))
- # 关闭数据库连接
- conn.close()
- # 向BUFF选品日志标签页的列表中写数据的槽函数
- @pyqtSlot(str, str, str, str, str, str, str, str)
- def _add_select_log(self, item_id, item_name, min_wear, max_wear, min_full_wear_price, sweep_price, judge_price,
- timestamp):
- # 创建一个字典来存储记录的详细信息
- record = {
- '商品ID': item_id,
- '商品名称': item_name,
- '磨损最低值': min_wear,
- '磨损最高值': max_wear,
- '全磨损区间最低价': min_full_wear_price,
- '扫货价': sweep_price,
- '判断价': judge_price,
- '时间': timestamp
- }
- row_count = self.select_log_tree_widget.topLevelItemCount()
- # 将新记录添加到树形控件中
- item = QTreeWidgetItem(self.select_log_tree_widget)
- # item.setText(0, "") # 选择列为空
- item.setText(0, str(row_count + 1)) # 设置序号
- item.setText(1, record['商品ID'])
- item.setText(2, record['商品名称'])
- item.setText(3, str(record['磨损最低值']))
- item.setText(4, str(record['磨损最高值']))
- item.setText(5, str(record['全磨损区间最低价']))
- item.setText(6, str(record['扫货价']))
- item.setText(7, str(record['判断价']))
- item.setText(8, record['时间'])
- # 创建复选框
- # checkbox = QCheckBox()
- # checkbox.setChecked(False)
- # self.select_log_tree_widget.setItemWidget(item, 0, checkbox)
- if __name__ == "__main__":
- app = QApplication(sys.argv)
- window = MainWindow()
- window.show()
- sys.exit(app.exec())
- # def setup_phone_edit_map(self):
- # self.phone_edit_map = {}
- # self.email_edit_map = {}
- # self.email_alias_edit_map = {}
- #代码备份 发送商家报价的代码
- #res = req.post(self.buyGoodsUrl, headers=api_header, data=api_data)
- #logger.debug(f'post 请求 {self.buyGoodsUrl} 返回报文: {res.text.strip()}')
- #if res.json()['code'] == 'OK':
- # logger.debug(f'购买成功')
- # time.sleep(float(self.pause_time_edit.text()))
- # logger.debug(f'post 请求 {self.buyGoodsUrl} 返回报文code等于OK,商品id:{goods_id}的磨损区间{goods_min_wear}-{goods_max_wear}的商品信息:{goods_item}')
- # try:
- # bill_order_id = res.json()['data']['id']
- # logger.debug(f'开始发报价 bill_order_id:{bill_order_id}')
- # # fbj_api_data=json.dumps({
- # # "bill_orders": [
- # # bill_order_id
- # # ],
- # # "game": "csgo"
- # # })
- # # logger.debug(f'fbj_api_data: { fbj_api_data }')
- # # fbj_api_header = {
- # # "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
- # # "Host": "buff.163.com", "X-Requested-With": "XMLHttpRequest",
- # # 'Referer': f"https://buff.163.com/market/buy_order/history?game=csgo",
- # # 'Cookie': self.cookie_text,
- # # "Content-Type":"application/json",
- # # 'x-csrftoken': "ImM2NTBjYmZhNjk2MGRjOWVkMTQxYjM5MTBjY2RhZjJjODRkNTBlMjUi.Z7WAmQ.yZ6n3Hcjv6eXHEElO1ZA95aqSEA"
- # # }
- # # todo 使用现有的工具,后续再开发
- # #fbj_res = req.post(self.fbjUrl, headers=fbj_api_header, data=fbj_api_data)
- # #logger.debug(f'post 请求 发报价 返回报文: {fbj_res.text.strip()}')
- # #if fbj_res.json()['code'] == 'OK':
- # # logger.debug(f'报价成功')
- # #else:
- # # logger.debug(f'报价失败')
- # except Exception as e:
- # logger.debug(f'商品发报价信息接口请求--失败', e)
- # try:
- # self.detail_logger.debug('选品接口请求参数列表 search_goods_param_list 长度:', len(self.search_goods_param_list))
- # # 遍历search_goods_param_list
- # while True:
- # #判断退出条件
- # if self.stop_selecting_flag:
- # self.detail_logger.debug('停止选品')
- # return
- # # 判断选品停止条件来判断是否需要终止
- # if self.stop_condition == '按照成功数量':
- # self.detail_logger.debug(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- # if int(self.success_count) <= int(self.search_success_count):
- # return
- # else:
- # # 按照选品数量来判断是否要停止
- # self.detail_logger.debug(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- # if int(self.scan_count) <= int(self.searchedGoodsNum):
- # return
- # for i in range(len(self.search_goods_param_list)):
- # try:
- # if self.stop_selecting_flag:
- # self.detail_logger.debug('停止选品')
- # return
- # # 判断选品停止条件来判断是否需要终止
- # if self.stop_condition == '按照成功数量':
- # self.detail_logger.debug(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- # if int(self.success_count) <= int(self.search_success_count):
- # return
- # else:
- # # 按照选品数量来判断是否要停止
- # self.detail_logger.debug(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- # if int(self.scan_count) <= int(self.searchedGoodsNum):
- # return
- # pagenum = 1
- # j = pagenum
- # first_flag = True
- # while int(j) <= int(pagenum):
- # datalist = []
- # if self.stop_selecting_flag:
- # self.detail_logger.debug('停止选品')
- # return
- # # 判断选品停止条件来判断是否需要终止
- # if self.stop_condition == '按照成功数量':
- # self.detail_logger.debug(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- # if int(self.success_count) <= int(self.search_success_count):
- # return
- # else:
- # # 按照选品数量来判断是否要停止
- # self.detail_logger.debug(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- # if int(self.scan_count) <= int(self.searchedGoodsNum):
- # return
- # if not first_flag:
- # self.search_goods_param_list[i]['page_num'] = j
- # self.detail_logger.debug(f"第{j}/{pagenum}页,API请求参数为:{self.search_goods_param_list[i]}")
- # else:
- # self.search_goods_param_list[i]['page_num'] = 1
- # self.detail_logger.debug(f"新查询条件第一次预请求,API请求参数为:{self.search_goods_param_list[i]}")
- # try:
- # # 开始时间为当前时间
- # current_time = time.time()
- # time_since_last_request = current_time - self.last_xp_request_time
- # if time_since_last_request < float(self.pause_time):
- # wait_time = float(self.pause_time) - time_since_last_request
- # self.detail_logger.debug(f"暂停 {wait_time:.2f} seconds before making the next request.")
- # time.sleep(wait_time)
- # api1_res = req.get(url=self.xp_goodsurl, headers=self.xp_my_headers,
- # params=self.search_goods_param_list[i])
- # self.detail_logger.debug('遍历商品接口请求返回报文:', api1_res.text.strip()[:50])
- # self.detail_logger.debug('遍历商品接口请求返回报文中的CODE:', api1_res.json()['code'])
- # if api1_res.json()['code'] == 'Captcha Validate Required':
- # self.detail_logger.debug(f'选品接口请求返回报文code为Captcha Validate Required,暂停{self.needed_msg_check_pause_time}秒后重试')
- # retry_count = 0
- # while retry_count < int(self.needed_msg_check_try_times):
- # self.detail_logger.debug(f'选品获取商品信息接口请求返回报文code为Captcha Validate Required,第{retry_count + 1}次重试')
- # time.sleep(int(self.needed_msg_check_pause_time))
- # api1_res = req.get(url=self.xp_goodsurl, headers=self.xp_my_headers,
- # params=self.search_goods_param_list[i])
- # # data = api1_res.json()['data']
- # if api1_res.json()['code'] == 'System Error':
- # continue
- # if api1_res.json()['code'] == 'OK':
- # break
- # if api1_res.json()['code'] == 'Captcha Validate Required':
- # retry_count += 1
- # if api1_res.json()['code'] == 'Captcha Validate Required':
- # self.detail_logger.debug('选品获取商品信息接口请求返回报文code仍然为Captcha Validate Required,跳出循环')
- # return
- # elif api1_res.json()['code'] != 'OK':
- # # 如果data中的code不等于OK,则跳出循环
- # self.detail_logger.debug('选品接口请求返回报文:', api1_res.text.strip()[:50])
- # self.detail_logger.debug('选品接口请求返回报文code不等于OK,跳出循环')
- # continue
- # data = api1_res.json()['data']
- # datalist.extend(data['items'])
- # # 遍历datalist
- # for k in range(len(datalist)):
- # # 做终止判断是否点击了停止选品按钮
- # if self.stop_selecting_flag:
- # self.detail_logger.debug('停止选品')
- # return
- # # 判断选品停止条件来判断是否需要终止
- # if self.stop_condition == '按照成功数量':
- # self.detail_logger.debug(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- # if int(self.success_count) < int(self.search_success_count):
- # return
- # else:
- # # 按照选品数量来判断是否要停止
- # self.detail_logger.debug(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- # if int(self.scan_count) < int(self.searchedGoodsNum):
- # return
- # self.detail_logger.debug(f'商品id:{str(datalist[k]["id"])}开始进行价格分析')
- # # 选品的数量+1
- # self.searchedGoodsNum += 1
- # # 1、获取磨损信息
- # PaintwearChoicesReturn = BUFFAPI.getPaintwearChoices(self, datalist[k]["id"])
- # # 多次出现需要验证短信的异常,停止选品进程
- # if PaintwearChoicesReturn == 'stop_flag':
- # self.detail_logger.debug(f'获取商品id:{datalist[k]["id"]}磨损信息失败,跳出进程')
- # return
- # if len(self.paintwear_choices) <= 0:
- # self.detail_logger.debug(f'获取商品id:{datalist[k]["id"]}磨损信息失败,筛选不满足条件,继续下次循环')
- # continue
- # # 1、先获取全磨损的最低价 170
- # PaintwearChoicesMinPriceReturn = BUFFAPI.getPaintwearChoicesMinPrice(self, datalist[k]["id"], '', '')
- # if PaintwearChoicesMinPriceReturn == 'stop_flag':
- # self.detail_logger.debug(f'获取商品id:{datalist[k]["id"]}全磨损最低价格连续出现短信验证异常,筛选不满足条件,退出进程')
- # return
- # min_price = float(PaintwearChoicesMinPriceReturn)
- # # min_price为0 则continue
- # if min_price == 0:
- # self.detail_logger.debug(f'获取商品id:{datalist[k]["id"]}全磨损的最低价为0,筛选不满足条件,继续下次循环')
- # continue
- # # 每个磨损区间的最低价
- # min_price_list = []
- # # 2、获取每个磨损区间的最低价 270 260 230 240 170
- # break_flag = False
- # for i3 in range(len(self.paintwear_choices)):
- # # 做终止判断是否点击了停止选品按钮
- # if self.stop_selecting_flag:
- # self.detail_logger.debug('停止选品')
- # return
- # PaintwearChoicesMinPriceReturn1 = BUFFAPI.getPaintwearChoicesMinPrice(self, datalist[k]["id"],
- # self.paintwear_choices[
- # i3][0],
- # self.paintwear_choices[
- # i3][1])
- # if PaintwearChoicesMinPriceReturn1 == 'stop_flag':
- # self.detail_logger.debug(f'获取商品id:{datalist[k]["id"]}磨损区间最低价格连续出现短信验证异常,筛选不满足条件,退出进程')
- # return
- # min_price_list.append(
- # {
- # 'min_wear': self.paintwear_choices[i3][0],
- # 'max_wear': self.paintwear_choices[i3][1],
- # 'min_price': float(PaintwearChoicesMinPriceReturn1)
- # }
- # )
- # self.detail_logger.debug(f'获取商品id:{datalist[k]["id"]}磨损区间及最低价信息:', min_price_list)
- # # todo 区间内容有价格为0,则跳过该商品,跳到下一个商品
- # for i2 in range(len(min_price_list)):
- # if min_price_list[i2]['min_price'] == 0:
- # self.detail_logger.debug(f'获取商品id:{datalist[k]["id"]}磨损区间及最低价信息:', min_price_list)
- # self.detail_logger.debug(
- # f'获取商品id:{datalist[k]["id"]}磨损区间及最低价信息中,有价格是0,跳过该商品')
- # break_flag = True
- # if break_flag:
- # self.detail_logger.debug(f'商品id:{datalist[k]["id"]} 筛选不满足条件,继续下次循环')
- # continue
- # # 3、全区间的最低价 170 * (1+10%),10%是设定的 = 187元
- # pd_price = round(min_price * (100 + self.ref_price_adjust) / 100, 4)
- # # 4、将5个磨损区间的最低价跟187比对,只留高于这个187价格的区间
- # # 遍历 min_price_list
- # for i1 in range(len(min_price_list)):
- # if min_price_list[i1]['min_price'] < pd_price:
- # # min_price_list 删除i1及以后的元素
- # min_price_list = min_price_list[:i1]
- # break
- # # 5、根据阶梯来确定磨损区间
- # # 遍历 min_price_list,判断元素中的min_price是否小于上一个元素的min_price,
- # for i2 in range(len(min_price_list) - 1):
- # if min_price_list[i2]['min_price'] < min_price_list[i2 + 1]['min_price']:
- # # min_price_list 删除i2及以后的元素
- # min_price_list = min_price_list[:i2 + 1]
- # break
- # # 6、170*(1+0.02)= 173.4 购买溢价
- # gm_price = round(min_price * (100 + self.sweep_price_adjust) / 100, 4)
- # # min_price_list 为空则继续下次循环
- # if len(min_price_list) <= 0:
- # self.detail_logger.debug(f'商品id:{datalist[k]["id"]} 筛选不满足条件,继续下次循环')
- # continue
- # # 向BUFF选品日志标签页中添加一条数据
- # timestamp = time.time()
- # local_time = time.localtime(timestamp)
- # formatted_time = time.strftime('%Y-%m-%d %H:%M:%S', local_time)
- # self.detail_logger.debug(f'商品id:{datalist[k]["id"]} 筛选成功, 磨损及价格区间min_price_list:',
- # min_price_list)
- # # 向BUFF选品日志标签页中增加记录 发出信号而不是直接调用 add_select_log
- # self.log_added.emit(str(datalist[k]["id"]), str(datalist[k]["name"]),
- # str(min_price_list[0]['min_wear']),
- # str(min_price_list[-1]['max_wear']), str(min_price), str(gm_price),
- # str(pd_price), str(formatted_time))
- #
- # conn = sqlite3.connect('buff.db')
- # cursor = conn.cursor()
- # cursor.execute('''
- # INSERT INTO select_logs (item_id, item_name, min_wear, max_wear, min_full_wear_price, sweep_price, judge_price, timestamp)
- # VALUES (?, ?, ?, ?, ?, ?, ?, ?)
- # ''', (datalist[k]["id"], datalist[k]["name"], min_price_list[0]['min_wear'], min_price_list[-1]['max_wear'], min_price, gm_price, pd_price, formatted_time))
- #
- # # 提交更改并关闭连接
- # conn.commit()
- # conn.close()
- # # 检索成功数量+1
- # self.search_success_count += 1
- # if not first_flag:
- # j += 1
- # if first_flag:
- # if int(data['total_page']) < int(self.max_page):
- # pagenum = data['total_page']
- # else:
- # pagenum = self.max_page
- # j = 1
- # first_flag = False
- # except Exception as e:
- # self.detail_logger.debug('选品接口1请求--失败', e)
- # j = 1
- # pagenum = 0
- # finally:
- # # self.last_goodsinfo_request_time = time.time() # 更新上次请求时间为当前时间
- # pass
- # except Exception as e:
- # self.detail_logger.debug('选品接口2请求--失败', e)
- # except Exception as e:
- # self.detail_logger.debug('选品接口3请求--失败', e)
- # finally:
- # # 扫货self.button_sh 和停止扫货self.button_stop_sh按钮不可点击
- # self.button_sh.setEnabled(True)
- # self.button_stop_sh.setEnabled(True)
- # self.detail_logger.debug('停止选品')
|