简体   繁体   中英

Python Pause loop on input

I have a loop that is processing a block of actions:

import threading
from selenium import webdriver
import os
from time import sleep
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
import threading
import time, random

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 = driver.find_element_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(0.8)
        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.click()
        time.sleep(0.8)
        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 = driver.find_element_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(0.8)
        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 = driver.find_element_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(0.8)
        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 = driver.find_element_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(0.8)
        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 = driver.find_element_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(0.8)
        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 = driver.find_element_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(0.8)
        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 = driver.find_element_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(0.8)
        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 = driver.find_element_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(0.8)
        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

options = Options()
#options.add_argument('headless')
options.add_argument('user-data-dir=C:\\Users\\timth\\AppData\\Local\\Google\\Chrome\\User Data\\')
driver = webdriver.Chrome(executable_path='C:\\Users\\timth\\Documents\\GitHub\\trade_helper\\chromedriver.exe', options=options)

# Open session
driver.get('https://www.xxxxxxxx')

time.sleep(10)

wait = WebDriverWait(driver, 3)


def wait_filters_set_up():
    # ask user to set up search filters
    while True:
        user_input_filters = input("Set up filters and type 'go' to continue\n")
        if user_input_filters != "go":
            print("Type 'go' to continue\n")
            continue
        else:
            break

def wait_user_start():
    # request user input start
    global bol_start_tool
    bol_start_tool = False
    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 {int_user_input_max_price} coins')
    time.sleep(3)

    while True:
        user_input_start = input("Press ENTER to start \n")
        if user_input_start != "":
            print("Press ENTER!")
            continue
        else:
            bol_start_tool = True
            break

def start_process():
    # actual start of PROCESS
    global bol_start_tool, continue_global, continue_process
    if bol_start_tool:
        continue_process = True

        thread_1 = threading.Thread(target=stop_or_restart)
        thread_1.daemon = True # without the daemon parameter, the function in parallel will continue even if your main program ends
        thread_1.start()

        print("Processing...")
        example_of_process()

def stop_or_restart():
    global continue_process, continue_global, count
    while continue_process:
        user_input = input("You can restart with R + Enter\n or stop with S + Enter \n")
        if user_input == 's':
            continue_process = False
            continue_global = False
            print("End of program, bye :)")
        if user_input == 'r':
            continue_process = False
            count = 0
            print("Restarting")

def example_of_process():
    global continue_process, count, int_user_input_max_price
    while continue_process:
        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(2)

        # Set min price
        int_players_bought = 0
        int_min_price = 200

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

            if int_min_price >= int_user_input_max_price:
                int_min_price = 200

            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[5]/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
            time.sleep(random.randint(1, 4))  # random sleep timer
            # print(f'Random delay is {}')
            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 him. Else go back to search directly

            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[1]/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)
                    int_min_player_buy_now_value = min(lst_price)
                    time.sleep(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(1)

                    # 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(1)

                    # 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:
                        ipt_buy_now_price.send_keys(str(int(int_min_player_buy_now_value)))
                        int_expected_profit = int((int_min_player_buy_now_value - int_player_price) * 0.95)
                    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)
                    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)}/25')
                    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 < 1000:
                int_min_price += 50
            elif int_min_price < 10000:
                int_min_price += 100
            elif int_min_price < 100000:
                int_min_price += 250
            else:
                int_min_price += 1000


def main_function():
    global continue_global, count
    continue_global = True
    count = 0
    while continue_global:
        wait_filters_set_up()
        wait_user_start()
        start_process()

main_function()

The part starting a #MY CODE... is beeing repeated infinitely,

I need to find a way, that the user has the chance to stop the process and also to restart the process.

The restart should start at "# ask user to set up search filters" because normally this case comes up when the user wants to stop, to change his searching filters.

Currently I am not working with a GUI (it is palnned tho) so I thought about setting up two user input options one for stop and one for restarting.

I am using selenium with chromedriver, so a total shutdown of the program and a manual relaunch would not be a solution. Since then the user would have to re-login etc. everytime he wants to make change in filters.

Is there any way, I could implement these two functions into my code?

Or do you have any advice how I would have to re-wright m code to make it work?

Any help is highly appreciated.

EDIT: @phoenix this is what I made of your code. I have update my hole code above.

You need a global while loop so it is easier to manage the "Restart" or the "Stop". I also changed your code into functions so it is clearer . And for a GUI or parallel actions in general, have a look at threading

def wait_filters_set_up():
    # ask user to set up search filters
    while True :
        user_input_filters = input("Set up filters and type 'go' to continue\n")
        if user_input_filters != "go":
            print("Type 'go' to continue\n")
            continue
        else:
            break

def wait_user_start():
    # request user input start
    global bol_start_tool
    bol_start_tool = False
    while True:
        user_input_start = input("Press ENTER to start \n")
        if user_input_start != "":
            print("Press ENTER!")
            continue
        else:
            bol_start_tool = True
            break

def start_process():
    # actual start of PROCESS
    global bol_start_tool, continue_global
    if bol_start_tool:
        print("Processing...")

        continue_process = True
        while continue_process:
            user_input = input("You can restart with R + Enter\n or stop with S + Enter \n")
            if user_input == 's':
                continue_process = False
                continue_global = False
                print("End of program, bye :)")
            if user_input == 'r':
                continue_process = False
                print("Restarting")

def main_function():
    global continue_global
    continue_global = True
    while continue_global:
        wait_filters_set_up()
        wait_user_start()
        start_process()

main_function()

EDIT : now I use a thread to have 2 actions in parallel: your main process, and a functions that is waiting for user input (Stop or Restart). Here I implemented a basic counter to simulate your main process.

import threading
import time

def wait_filters_set_up():
    # ask user to set up search filters
    while True :
        user_input_filters = input("Set up filters and type 'go' to continue\n")
        if user_input_filters != "go":
            print("Type 'go' to continue\n")
            continue
        else:
            break

def wait_user_start():
    # request user input start
    global bol_start_tool
    bol_start_tool = False
    while True:
        user_input_start = input("Press ENTER to start \n")
        if user_input_start != "":
            print("Press ENTER!")
            continue
        else:
            bol_start_tool = True
            break

def start_process():
    # actual start of PROCESS
    global bol_start_tool, continue_global, continue_process
    if bol_start_tool:
        continue_process = True

        thread_1 = threading.Thread(target=stop_or_restart)
        thread_1.daemon = True # without the daemon parameter, the function in parallel will continue even if your main program ends
        thread_1.start()

        print("Processing...")
        example_of_process()

def stop_or_restart():
    global continue_process, continue_global, count
    while continue_process:
        user_input = input("You can restart with R + Enter\n or stop with S + Enter \n")
        if user_input == 's':
            continue_process = False
            continue_global = False
            print("End of program, bye :)")
        if user_input == 'r':
            continue_process = False
            count = 0
            print("Restarting")

def example_of_process():
    global continue_process, count
    while continue_process:
        print("count", count)
        count += 1
        time.sleep(1)

def main_function():
    global continue_global, count
    continue_global = True
    count = 0
    while continue_global:
        wait_filters_set_up()
        wait_user_start()
        start_process()

main_function()

Wrap the 2 while loops in a function. Then whenever you want to leave the function you just return out of it. Whenever you wanna redo the process you just call the function again.

need_to_stop = False

While !need_to_stop:    
    # ask user to set up search filters
    While True:
      user_input_filters = input("Set up filters and type 'go' to continue")
      # ***


    bol_start_tool = False

    # request user input start
    While True:
      user_input_start = input("Press ENTER to start")
      # ***

    # actual start of PROCESS
    if bol_start_tool:

    # MY CODE FOR PROCESS (searching according to the filters and further on working with the results)
    break; # <- this is your solution

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM