Threading - Start Stop

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
exec85
User
Beiträge: 1
Registriert: Donnerstag 30. Januar 2020, 09:53

Guten Morgen,

bevor ich euch meine Frage stelle wollte ich kur erwähnen, das ich mir derzeit in meiner Freizeit Python selbst beibringe.
Als mein erstes Projekt habe ich mir die automatisierte Bedienung einer Web App mit Selenium ausgesucht.
Es zeigt sich, dass ich darüber deutlich schneller lerne als über das Anschauen Stundenlanger Tutorials bei Youtube.

zur Erklärung, was mein Programm macht, vlt noch ein paar Worte.
Ich spiele hobby mäßig gerne mal ne Runde Fifa 20 auf der PS4. Fifa 20 hat eine Web App, über die man Spieler kaufen und verkaufen kann, bzw. seinen Verein verwalten kann.
Mein Programm sucht nun in der Web App gezielt nach bestimmten Spielern (die zu günstig eingestellt wurden), kauft diese und stellt sie wieder zum aktuellen Marktwert zum Verkauf ein.
Somit kann ich während ich auf der Arbeit bin Spielewährung für meinen Verein erwirtschaften.

Das Programm habe ich so aufgebaut, dass man entweder die die option 1 (start buy only mode) oder option 2 (# Start full routine) wählen kann.
Je nach dem welche option gewählt wurde, wird eine der beiden while Schleifen aktiviert.

Ich suche nun schon seit Tagen nach einer Lösung, we ich hier eine Start / Stop Funktion einbauen kann. Denn aktuell ist es so, dass wenn ich den Prozess unterbrechen möchte, um z. B. in der Web App kurz etwas manuell anzuschauen, immer den ganzen Prozess beenden muss, also auch den chromedriver etc. und im Prinzip die .py erst wieder starten muss.

Ich habe nun gelesen dass man dies mit Threading abdecken kann, jedoch muss ich sagen, dass ich da absolut nicht weiter komme. Daher die Hoffnung, dass ihr mir evtl. bei erin Lösung helfen könnt?

Ich komme nicht dahinter, wie ich den Code umschreiben müsste, dass ich die Möglichkeit habe in der Konsole per "start" oder "stop" Eingabe, den Prozess anzuhalten oder neu zu starten. Der Neustart bzw. reset sollte dann wieder zur Abfrage führen, ob man Option 1 oder 2 nutzen möchte.

Anbei mein code:

Code: Alles auswählen

import os, time, random
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options

def random_sleep_timer(min,max):
    int_random_sleep_timer = random.randint(min,max)
    time.sleep(int_random_sleep_timer)

def calculate_expected_profit(int_min_player_buy_now_value, int_player_price):
    if int_min_player_buy_now_value > int_player_price:
        ipt_buy_now_price.send_keys(str(int(int_min_player_buy_now_value)))
        int_expected_profit = int((int_min_player_buy_now_value * 0.95) - int_player_price)
    else:
        ipt_buy_now_price.send_keys(str(int(int_player_price * 1.25)))
        int_expected_profit = int(((int_player_price * 1.25) - int_player_price) * 0.95)

def get_player_prices(driver):
    lst_price = []
    #Determine list of first 20 cards
    lst_cards = driver.find_element_by_class_name("ui-layout-right") \
        .find_element_by_class_name("paginated-item-list") \
        .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
    #Loop through list of first 20 cards and determine prices
    for card in lst_cards:
        str_player_buy_now_value = card.find_element_by_xpath("..") \
            .find_element_by_class_name("currency-coins").text
        int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
        lst_price.append(int_player_buy_now_value)
    #Try with the next 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try to determine third 20 entries
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,
                                               '/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try with the fourth 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try with the 5th 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try with the 6th 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try with the 7th 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try with the 8th 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try with the 9th 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price
    #Try with the 10th 20 cards
    try:
        btn_next = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/section/div[2]/div/button[2]')))
        btn_next.click()
        time.sleep(1)
        lst_cards = driver.find_element_by_class_name("ui-layout-right") \
            .find_element_by_class_name("paginated-item-list") \
            .find_elements_by_xpath(".//*[contains(text(), 'Buy Now')]")
        # Loop through list of first 20 cards and determine prices
        for card in lst_cards:
            str_player_buy_now_value = card.find_element_by_xpath("..") \
                .find_element_by_class_name("currency-coins").text
            int_player_buy_now_value = int(str_player_buy_now_value.replace(",", "").strip())
            lst_price.append(int_player_buy_now_value)
    except:
        return lst_price

    return lst_price

script_path = os.path.dirname(os.path.abspath( __file__ ))

print('License is valid!')
print('HWID f0Ghrit-fgetr-hju73ger5-556tgr')


# Initiate driver
options = Options()
options.add_argument(f'user-data-dir={script_path}\\User Data\\profile')
driver = webdriver.Chrome(executable_path=f'{script_path}\\chromedriver.exe', options=options)

# Open session
driver.get('https://www.easports.com/en/fifa/ultimate-team/web-app/')

time.sleep(10)

print("Initializing trade_buddy...")
print("Please frequently check Discord for updates!")
time.sleep(3)

wait = WebDriverWait(driver, 2)

# Log in to web app
try:
    btn_login_app = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="Login"]/div/div/button[1]')))
    btn_login_app.click()
except:
    pass

# ask user to log in to web app
print("Logging in...")
time.sleep(5)

# ask user to define the filters
while True:
    user_input_filters = input("Choose your search filters and type 'go' to continue:")
    if user_input_filters != "GO" and user_input_filters != "Go" and user_input_filters != "go":
        print("Choose your search filters and type 'go' to continue:")
        continue
    else:
        if user_input_filters == "GO" or user_input_filters =="Go" or user_input_filters == "go":
            user_input_filters = False
        break

time.sleep(1)

# set max BIN price
while True:
    user_input_max_price = input('Enter max buy now price (>250):')
    if user_input_max_price.isdigit():
        int_user_input_max_price = int(user_input_max_price)
        if int_user_input_max_price > 250:
            break
        else:
            print('Max buy now price must be >250')
            continue
    else:
        print('Enter max buy now price (>250):')
        continue

print(f'Max BIN set to {str(int_user_input_max_price)} coins')
time.sleep(3)

bol_start_bot_buy_only = False
bol_start_bot_full = False


# start bot with option input
while True:
    user_input_start = int(input("Enter '1' for BUY ONLY or '2' for FULL ROUTINE:"))
    if user_input_start == 1:
        print("BUY only mode starting in 5 seconds.....")
        print("Please make the chrome window active!")
        bol_start_bot_buy_only = True
        break
    if user_input_start == 2:
        print("FULL ROUTINE mode starting in 5 seconds.....")
        print("Please make the chrome window active!")
        bol_start_bot_full  = True
        break
    else:
        print('Please enter a valid option (1 or 2)')
        continue


time.sleep(5)
print("Running...")

# Start full routine
if bol_start_bot_full:

    time.sleep(1)
    btn_search = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div[2]/div/div[2]/button[2]')

   # filters.predefine_filters_in_search_mask()

    # set max price
    ipt_max_price = driver.find_element_by_xpath(
        "/html/body/main/section/section/div[2]/div/div[2]/div/div[1]/div[2]/div[6]/div[2]/input")
    ipt_max_price.click()
    time.sleep(1)
    ipt_max_price.send_keys(int_user_input_max_price)
    time.sleep(1)

    # Set min price
    int_min_price = 150

    # Set max players bought
    int_max_players_bought = 100
    int_players_bought = 0


    # Buy until 25 players were bought
    while int_players_bought < int_max_players_bought:

        if int_min_price >= int_user_input_max_price:
         int_min_price = 150

        ipt_min_price = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[2]/div/div[2]/div/div[1]/div[2]/div[2]/div[2]/input')))
        ipt_min_price.clear()
        ipt_min_price.click()
        time.sleep(0.5)
        ipt_min_price.send_keys(int_min_price)
        time.sleep(0.5)
        # click search button
        random_sleep_timer(1,2)
        btn_search = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div[2]/div/div[2]/button[2]')
        btn_search.click()

        # if player is found, buy it. Else go back to the search view
        try:
            btn_buy_now = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[2]/div[2]/button[2]')))
            btn_buy_now.click()
            confirm_button = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[4]/section/div/div/button[1]')))
            confirm_button.click()
            time.sleep(1)
            try:
                time.sleep(1)
                btn_price_check = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[2]/div[3]/button[8]')))
                btn_price_check.click()

                lst_price = get_player_prices(driver)
                lst_price.sort()
                lst_price_sorted = sorted(lst_price)[:3]

                if len(lst_price_sorted) >= 3:
                    int_min_player_buy_now_value = int(sum(lst_price_sorted) / len(lst_price_sorted))
                    if int_min_player_buy_now_value < 1000:
                        int_min_player_buy_now_value -= 50
                    else:
                        int_min_player_buy_now_value = int((sum(lst_price_sorted) / len(lst_price_sorted))*0.98)

                    time.sleep(0.1)
                else:
                    int_min_player_buy_now_value = int(sum(lst_price_sorted) / len(lst_price_sorted))
                    if int_min_player_buy_now_value < 1000:
                        int_min_player_buy_now_value -= 50
                    else:
                        int_min_player_buy_now_value = int((sum(lst_price_sorted) / len(lst_price_sorted))*0.98)
                    time.sleep(0.1)

                #Determine + click Back button
                btn_back_from_price_check = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div[1]/button')
                btn_back_from_price_check.click()
                time.sleep(2)

                # Determine player name + price payed
                div_player_name = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[1]/div/ul/li/div/div[1]/div[2]')
                str_player_name = div_player_name.text
                int_player_price = int(driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[2]/div[1]/div[2]/div/span[2]').text.replace(",",""))

                # Determine + click List Player on Market button
                time.sleep(1)
                btn_list_player_on_market = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/div/div[2]/div[2]/div[1]/button')
                btn_list_player_on_market.click()
                time.sleep(2)

                # Determine + fill Start Price Input field
                ipt_start_price = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/div/div[2]/div[2]/div[2]/div[2]/div[2]/input')
                ipt_start_price.click()
                time.sleep(1)
                ipt_start_price.send_keys("9999999999")
                time.sleep(1)

                # Determine + fill Buy Now Price Input field
                ipt_buy_now_price = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/div/div[2]/div[2]/div[2]/div[3]/div[2]/input')
                ipt_buy_now_price.click()
                time.sleep(1)

                # Pricing
                if int_min_player_buy_now_value > (int_player_price*1.05):
                    ipt_buy_now_price.send_keys(str(int(int_min_player_buy_now_value)))
                    int_expected_profit = int((int_min_player_buy_now_value * 0.95) - int_player_price)
                else:
                    ipt_buy_now_price.send_keys(str(int(int_player_price*1.05)))
                    int_expected_profit = int(((int_player_price*1.05) - int_player_price)*0.95)
                time.sleep(1)

                # List player on market
                btn_list_player = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div[2]/div/div[2]/div[2]/div[2]/button')
                btn_list_player.click()
                # btn_send_to_transfer_list = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[2]/div[3]/button[7]')))
                # btn_send_to_transfer_list.click()
                int_players_bought += 1  # increment players bought count
                print(f'Bought player: {str_player_name} for {int_player_price}')
                print(f'Estimated profit: {int_expected_profit}')
                print(f'Player counter {str(int_players_bought)}/{str(int_max_players_bought)}')
                print('Searching...')
                time.sleep(1)
                btn_back = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[1]/button[1]')))
                btn_back.click()

            except:
                time.sleep(1)
                btn_back = wait.until(
                EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[1]/button[1]')))
                btn_back.click()

        except:
            time.sleep(1)
            btn_back = wait.until(
                EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[1]/button[1]')))
            btn_back.click()

        time.sleep(0.5)
        if int_min_price < 950:
            int_min_price += 50
        elif int_min_price < 9000:
            int_min_price += 100
        elif int_min_price < 100000:
            int_min_price += 250
        else:
            int_min_price += 1000

# start buy only mode
if bol_start_bot_buy_only:
    
    time.sleep(1)
    btn_search = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div[2]/div/div[2]/button[2]')

    # set max price
    ipt_max_price = driver.find_element_by_xpath(
        "/html/body/main/section/section/div[2]/div/div[2]/div/div[1]/div[2]/div[6]/div[2]/input")
    ipt_max_price.click()
    time.sleep(1)
    ipt_max_price.send_keys(int_user_input_max_price)
    time.sleep(1)

    # Set min price
    int_min_price = 150

    # Set max players bought
    int_max_players_bought = 100
    int_players_bought = 0


    # Buy until 25 players were bought
    while int_players_bought < int_max_players_bought:

        if int_min_price >= int_user_input_max_price:
         int_min_price = 150

        ipt_min_price = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[2]/div/div[2]/div/div[1]/div[2]/div[2]/div[2]/input')))
        ipt_min_price.clear()
        ipt_min_price.click()
        time.sleep(0.5)
        ipt_min_price.send_keys(int_min_price)
        time.sleep(0.5)
        # click search button
        random_sleep_timer(1,2)
        btn_search = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div[2]/div/div[2]/button[2]')
        btn_search.click()

        # if player is found, buy it. Else go back to the search view
        try:
            btn_buy_now = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[2]/div[2]/button[2]')))
            btn_buy_now.click()
            confirm_button = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[4]/section/div/div/button[1]')))
            confirm_button.click()
            time.sleep(1)
            
            # send player to transfer list
            btn_snd_to_tfl = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[2]/div[3]/button[7]')))
            btn_snd_to_tfl.click()
            time.sleep(1)
            # variable for player name
            div_player_name_buy_only = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[1]/div/div/div/div[5]')
            str_player_name_buy_only = div_player_name_buy_only.text
            int_player_price = int(driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div/section[2]/div/div/div[2]/div[1]/div[2]/div/span[2]').text.replace(",",""))
            time.sleep(1)
            int_players_bought += 1  # increment players bought count
            print(f'Bought player: {str_player_name_buy_only} for {int_player_price}')
            print(f'Player counter {str(int_players_bought)}/{str(int_max_players_bought)}')
            print('Searching...')
            time.sleep(1)
            
            # back to search mask
            btn_back_to_mask = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[1]/button[1]')))
            btn_back_to_mask.click()
            time.sleep(2)
        except:
            # back to search mask
            btn_back_to_mask = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/section/section/div[1]/button[1]')))
            btn_back_to_mask.click()
                    
        time.sleep(0.5)
        if int_min_price < 950:
            int_min_price += 50
        elif int_min_price < 9000:
            int_min_price += 100
        elif int_min_price < 100000:
            int_min_price += 250
        else:
            int_min_price += 1000

Ich bedanke mich im Voraus fürs lesen und würde mich sehr darüber freuen wenn mir jemand von euch weiterhelfen könnte.

LG Tim
Antworten