не работает бот на selenium для редактирования цены ставки
принцип работы бота таков: каждые Х секунд бот парсит и обновляет список текущих ставок на коллекцию nft, есть моя ставка, а есть чужие. допустим, я указываю, что хочу чтобы моя ставка на 2 месте в списке ставок бот проверяет, если я уже на 2 месте - продолжает мониторить ставки, нет - запускает функцию изменения ставки. вот пример таблицы: https://ibb.co/jHM6fGj
бот берет значение ставки у юзера на 2 месте, в нашем случае 90.01 и добавляет к нему 0.005, тем самым ставка становится выше. нажимает нужные кнопки, такие как редактирование, подтверждает транзакцию в кошельке (в отдельном окне), проверяет, если есть текст done! your new order - транзакция подтверждена, окно закрывается и парсинг продолжается. если нет - идет на второй круг и пытается снова отправить транзакцию. и пока прописан старт - выводится мониторинг в 10 секунд какая ставка стоит и позиция на данный момент. все ставки продолжают парсится раз в Х секунд.
имеется консоль, в которой можно выбрать нужную мне позицию командой pos, можно запустить и приостановить работу бота и так же открыть коллекцию по ссылке и автоматически перейти во вкладку bids.
собственно, сама проблема заключается в том, что после start не происходит ровным счетом ничего - мониторинг не выводит раз в 10 секунд ничего, как и функция по получению ставок тоже. сложность парсинга еще заключается в том, что элементы имеют рандомную часть и отследить их довольно проблематично (возможно мне так кажется и на самом деле проще простого, но сделал так, как видел). пример коллекции где все это можно лицезреть: https://www.tensor.trade/trade/madlads. функция редактирования может выглядеть ужасно, признаю, но вы меня простите, я новичок :)
собственно, сам код:
from colorama import Fore
import re
import time
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.service import Service
from datetime import datetime
import threading
import logging
colorama.init()
logging.getLogger().setLevel(logging.CRITICAL)
display_bid_thread = None
update_bids_thread = None
pos = None
new_bid_amount = 0
is_running = False
profile_directory = r'C:\Users\k\Desktop\tensor\profile'
chromedriver_path = 'C:\\Users\\k\\Desktop\\tensor\\chromedriver.exe'
service = Service(chromedriver_path)
options = webdriver.ChromeOptions()
options.add_argument('--user-data-dir=' + profile_directory)
driver = webdriver.Chrome(service=service, options=options)
def get_current_time():
current_time = datetime.now().strftime("%H:%M:%S")
return current_time
def open_collection_page(collection_url):
driver.get(collection_url)
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | открываю ссылку. " + Fore.LIGHTRED_EX + "пожалуйста дождись" + Fore.RESET + " перехода на вкладку bids.")
time.sleep(5)
button = driver.find_element(By.ID, "tabs-:r1t:--tab-1")
button.click()
os.system('cls')
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | список доступных команд: 'open', 'start', 'pause', 'bids', 'pos', 'help', 'exit'")
def get_bids():
bids = []
elements = driver.find_elements(By.XPATH, "//p[contains(@class, 'chakra-text')]")
bid_texts = [element.text.strip() for element in elements]
for index, text in enumerate(bid_texts):
if "◎" in text:
bid_info = {}
price_match = re.search(r"◎(\d+\.\d{2})", text)
if price_match is not None:
price = price_match.group(1)
bid_info["price"] = price
quantity_match = re.search(r"\s+(\d+)\s+", text)
if quantity_match is not None:
quantity = quantity_match.group(1)
bid_info["quantity"] = int(quantity)
user_info = re.search(r"\b(?!HadeSwap|TensorSwap)(YOU|\w{5})\b", text, re.IGNORECASE)
if user_info is not None:
if user_info.group(0) == "YOU":
bid_info["is_your_bid"] = True
your_bid = {"price": price, "quantity": int(quantity), "position": index + 1, "is_your_bid": True}
bids.append(your_bid)
else:
bid_info["position"] = index + 1
bid_info["is_your_bid"] = False
bids.append(bid_info)
return bids
print(bids)
def update_bids():
global is_running
while is_running:
previous_bids = []
bids = get_bids()
for bid in bids:
if bid.get("is_your_bid") and bid.get("position") != pos:
other_bid_amount = bid.get("price")
edit_bid(other_bid_amount)
previous_bids = bids[:] # обновляем список предыдущих бидов
time.sleep(1)
def edit_bid(other_bid_amount): # меняем сумму бида
while True:
try:
edit_button = driver.find_element(By.XPATH, "./button[@aria-label='edit order']")
edit_button.click()
time.sleep(3)
try:
curve_type = driver.find_element(By.XPATH, "//div[text()='Curve type']") # проверяем открылось ли окно
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | открыл окно с редактированием бида.")
time.sleep(1)
try:
edit_button = driver.find_element(By.XPATH,
"//span[contains(@class, 'chakra-badge') and text()='EDIT']")
edit_button.click()
time.sleep(1)
try: # ищем поле для суммы
bid_amount_field = driver.find_element(By.XPATH,
"//div[contains(@class, 'chakra-numberinput')]")
current_bid_amount = bid_amount_field.get_attribute("value") # получаем текущее значение суммы ставки
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | текущий бид: ◎", current_bid_amount)
new_bid_amount = float(
other_bid_amount) + 0.005 # меняем бид на основе ставки другого юзера
new_bid_amount = str(new_bid_amount)
bid_amount_field.clear()
bid_amount_field.send_keys(new_bid_amount)
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | новый бид: ◎", new_bid_amount)
try: # находим кнопку APPLY CHANGES
apply_changes_button = driver.find_element(By.XPATH,
"//span[contains(@class, 'chakra-badge') and contains(text(), 'APPLY CHANGES')]")
apply_changes_button.click()
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | нажал apply changes.")
time.sleep(7)
driver.switch_to.window(driver.window_handles[-1]) # переключаемся на окно фантома
try: # подтверждаем транзу в фантоме
confirm_button = driver.find_element(By.XPATH,
"//button[@type='submit' and @data-testid='primary-button']")
confirm_button.click()
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | подтвердил транзу в фантоме, ждем попадания в блок.")
driver.switch_to.window(driver.window_handles[0]) # переключаемся на основное окно
time.sleep(10)
try:
done_text = driver.find_element(By.XPATH,
"//p[contains(@class, 'chakra-text') and contains(text(), 'Done! Your new order')]")
if done_text.is_displayed():
close_button = driver.find_element(By.XPATH,
"//button[@type='button' and @aria-label='Close']") # закрываем окно с ордером
close_button.click()
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | транза подтверждена. закрыл окно, продолжаю мониторить.")
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | выставил бид на " + Fore.CYAN + "◎" + new_bid_amount)
break # ливаем с цикла если все ок
else:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | транза фейлед. идем на второй круг.")
except NoSuchElementException:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | транза фейлед. идем на второй круг.")
except NoSuchElementException:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | я слепой, не могу найти кнопку в фантоме.")
driver.switch_to.window(driver.window_handles[0])
except NoSuchElementException:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | я слепой, не могу найти apply changes.")
except NoSuchElementException:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | я слепой, не могу найти поле с суммой бида.")
except NoSuchElementException:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | я слепой, не могу найти кнопку эдит в окне редактирования.")
except NoSuchElementException:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | не могу открыть окно редактирования бида..")
except NoSuchElementException:
pass
try: # если транза фейлед, закрываем окно и меняем бид снова
close_button = driver.find_element(By.XPATH, "//button[@type='button' and @aria-label='Close']")
close_button.click()
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | фейлед транза. закрываю окно.")
except NoSuchElementException:
pass
def start_threads():
global display_bid_thread, update_bids_thread
display_bid_thread = threading.Thread(target=display_bid_info, args=(display_bid_thread,))
display_bid_thread.start()
update_bids_thread = threading.Thread(target=update_bids)
update_bids_thread.start()
def pause_threads():
global display_bid_thread, update_bids_thread
if display_bid_thread is not None:
display_bid_thread.join()
if update_bids_thread is not None:
update_bids_thread.join()
def display_bid_info(display_thread):
global is_running
while is_running:
bids = get_bids()
for bid in bids:
if bid.get("is_your_bid") and bid.get("position") == pos:
bid_amount = bid.get("price")
position = bid.get("position")
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.RESET + "| bid: " + Fore.CYAN + "◎" + bid_amount + + Fore.RESET + "pos: ", Fore.LIGHTGREEN_EX + position)
break
time.sleep(10)
def main():
global display_bid_thread, update_bids_thread, is_running
is_running = False
while True:
command = input("> ")
if command == 'open':
collection_url = input("| введи url коллекции (прим. https://www.tensor.trade/trade/abc_abracadabra): ")
open_collection_page(collection_url)
if command == 'help':
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | open - открыть страницу коллекции.")
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | start - запустить скрипт.")
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | pause - остановить скрипт.")
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | bids - вывести список текущих ставок.")
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | pos - выбрать позицию для ребида.")
elif command == 'bids':
bids = get_bids()
for bid in bids:
print(bid)
elif command == 'start':
if is_running:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | бот уже работает.")
else:
is_running = True
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | бот запущен.")
start_threads()
elif command == 'pause':
if is_running:
is_running = False
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | бот остановлен.")
pause_threads(display_bid_thread, update_bids_thread)
else:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | бот не запущен.")
elif command == 'exit':
break
elif command == 'pos':
pos = input("| введи нужную позицию: ")
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | позиция " + Fore.LIGHTCYAN_EX + pos + Fore.RESET + " установлена.")
else:
print(Fore.LIGHTBLUE_EX + get_current_time() + Fore.WHITE + " | неправильная команда.")
driver.quit()
if __name__ == "__main__":
main()```