0

I am very much not experienced in coding and all my work here is done by research.

I am creating a python script which helps me add a ticket to basket via selenium however coming across some things im not sure how to do.

The ticketing website requires to sit and refresh the page until a ticket becomes available from another user and then a button becomes clickable which then allows you to reserve it.

I have created the 1st part of the script which opens up and link and click the button when its available however when its not available i need to page to refresh and attempt to click the button if available and repeat until hopefully succesful which by that point the script can stop.

When a ticket is added to basket the URL changes so that could be a condition for the script to check before stopping.

Below is the python code which contains the URL link where the button is not clickable.

To test the script working change the URL to this: https://ticketing.liverpoolfc.com/en-GB/events/liverpool%20women%20v%20everton%20women/2022-9-25_18.45/anfield?hallmap

The button that needs to be clicked is CHOOSE SEAT FOR ME

from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

PATH = "D:\chromedriver.exe"

driver = webdriver.Chrome(PATH)

driver.get("https://ticketing.liverpoolfc.com/en-GB/events/liverpool%20v%20newcastle%20united/2022-8-31_20.00/anfield?hallmap")


try:
    element = WebDriverWait(driver, 25).until(
        EC.element_to_be_clickable((By.XPATH,"/html/body/div[7]/div/button"))
    )
finally:
    print("Page loaded")

button = driver.find_element(By.XPATH, "/html/body/div[7]/div/div[4]/div[1]/div[3]/div[2]/div[2]/div/div[3]/div[1]/button[2]")
button.click()```




Prophet
  • 32,350
  • 22
  • 54
  • 79
David
  • 9
  • 3
  • So you need to driver.refresh() until the button is available which should be a simple break from a loop. So you could while True: try: #your code break except: driver.refresh() – Arundeep Chohan Aug 30 '22 at 18:34
  • As of the current state I find the button with text as **Choose seats for me** enabled. The HTML of the button when it's disabled would have helped to construct a canonical answer. – undetected Selenium Aug 30 '22 at 19:41
  • 1
    @undetectedSelenium You can find the button disabled here https://ticketing.liverpoolfc.com/en-GB/events/liverpool%20v%20newcastle%20united/2022-8-31_20.00/anfield?hallmap – David Aug 30 '22 at 19:44
  • @undetectedSelenium I managed to test it and ran into an issue, i made a video to try explain better :) https://youtu.be/fMAqozCgmgs – David Aug 31 '22 at 10:16

3 Answers3

2
 from selenium import webdriver
 from selenium.webdriver.common import action_chains
 from selenium.webdriver.common.keys import Keys
 from selenium.webdriver.common.by import By
 from selenium.webdriver.support.ui import WebDriverWait
 from selenium.webdriver.support import expected_conditions as EC
 import time
 from selenium.webdriver.common.action_chains import ActionChains
  
 driver = webdriver.Chrome()

While True:
 try:

 time.sleep(5)

 ActionChains(driver).move_to_element(
 driver.find_element(By.XPATH,'button').perform()

 if driver.find_element(By.XPATH,'button').is_enabled():
    driver.find_element(By.XPATH,'button').click()
    print('clicked')
    break
 else:
   driver.refresh()
 except Exception as e:
 print(f'button not found: {e}')
 continue  
  • On 'button' do i need to replce it with the actual xpath? or leave it how it is? – David Aug 30 '22 at 20:32
  • Replace with XPATH. Right-click on the button, go to inspect, then once you see the element you want highlighted, right-click and select copy XPATH. – Zachary Rizzo Aug 30 '22 at 20:34
1

As I see from your code, you do not actually clicking the /html/body/div[7]/div/button button. All what you trying to actually do here is to click the /html/body/div[7]/div/div[4]/div[1]/div[3]/div[2]/div[2]/div/div[3]/div[1]/button[2] button.
This element is disabled if This event is sold out. Please try again later notification is presented.
If so, you can make your code more clear and simple.
You can wait for a short time to find the /html/body/div[7]/div/div[4]/div[1]/div[3]/div[2]/div[2]/div/div[3]/div[1]/button[2] button enabled. In case this element is found disabled - refresh the page.
In case the button is found enabled - click it.
You can also improve your locators. As following:

from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

PATH = "D:\chromedriver.exe"

driver = webdriver.Chrome(PATH)

driver.get("https://ticketing.liverpoolfc.com/en-GB/events/liverpool%20v%20newcastle%20united/2022-8-31_20.00/anfield?hallmap")

while true:
    try:
        #try to find the button enabled
        #in case you found it enabled - click it
        WebDriverWait(driver, 5).until(
        EC.element_to_be_clickable((By.XPATH,"//button[@class='areas-filter-panel__find-button' and(not(@disabled))]")).click()
        #break the loop in case of successful click
        break
    except:
        #if button found disabled exception is thrown, catch catches it and performs a refresh
        driver.refresh()

Prophet
  • 32,350
  • 22
  • 54
  • 79
  • Hi @Prophet, thanks for your comment and solution. It looks like the script is now trying to do the action but when i tested it on a event where the button is enabled and working it still continues to refresh in a loop and doesnt try click the button. I wanted to paste the code here but its too long. You can replace the URL for this https://ticketing.liverpoolfc.com/en-GB/events/liverpool%20women%20v%20everton%20women/2022-9-25_18.45/anfield?hallmap and try run it yourself if you dont mind – David Aug 30 '22 at 19:24
  • that's strange... can you check and confirm that when the button is enabled it matches the XPath I used here? – Prophet Aug 30 '22 at 19:27
  • I can't run it on my PC, I even have no python on it.... – Prophet Aug 30 '22 at 19:27
  • It looks like you used the button class name isntead of the xpath The xpath is actually /html/body/div[7]/div/div[4]/div[1]/div[3]/div[2]/div[2]/div/div[3]/div[1]/button[2] – David Aug 30 '22 at 19:40
  • Correct. I used the unique locator instead of absolute xpath. The both locators are matching the same element. Except the `not` i have added with `disabled`. At least when it is disabled. This is why I asked you to confirm is that XPath still matches the element when it is enabled. – Prophet Aug 30 '22 at 19:45
  • When enabled it does not say enabled or anything with it. All there is: – David Aug 30 '22 at 19:47
  • Great! Because when it is disabled it contains `disabled` attribute. But when the element is enabled `disabled` attribute disappears. this is what `and(not(@disabled))` comes for – Prophet Aug 30 '22 at 19:49
  • So `//button[@class='areas-filter-panel__find-button' and(not(@disabled))]` should match it when it is enabled. – Prophet Aug 30 '22 at 19:49
  • Here is what happens when i run your recommended changes: https://gyazo.com/e9ff274be751615c2e415fd380404da2 – David Aug 30 '22 at 19:52
0

To refresh the website for the element Choose seats for me to be clickable you need to induce WebDriverWait for the element_to_be_clickable() and wrapping up the click event within a while-try-except{} block and you can use the following locator strategy:

driver.get('https://ticketing.liverpoolfc.com/en-GB/events/liverpool%20women%20v%20everton%20women/2022-9-25_18.45/anfield?hallmap')
while True:
    try:
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.areas-filter-panel__find-button"))).click()
        break
    except TimeoutException:
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='ui-button showPopupMessage-redbutton ui-corner-all ui-widget' and text()='OK']"))).click()
        driver.refresh()
        continue
# other lines of code
driver.quit()

Note : You have to add the following imports :

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Thanks for your suggestion, i ran it but it has not worked. See here what happens: https://gyazo.com/ddbe3041a54d21b79ad15cc5d95c138d Also an error showed up: https://gyazo.com/8e88fdb9b74d7712eb6a3abbe53dbdd2 – David Aug 30 '22 at 20:03
  • @David Checkout the updated answer and let me know the status. – undetected Selenium Aug 30 '22 at 20:11
  • 1
    Looks to be doing what is needed, i'm now trying to test it and hopefully a ticket becomes available. Esentially its first come first served on who can add the ticket to basket which is why im trying this. I reduced the wait time so that the refresh and clicks happen much quicker. I will let you know what happens :) – David Aug 30 '22 at 20:25
  • @David Great, go ahead and keep me updated about the status. – undetected Selenium Aug 30 '22 at 20:26