0

I fixed my previous problem with sys.argv (depends on how the .cmd file call the script).

Now I'm stuck with another trouble :

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

I read quite a lot about this but I am still confused how to deal with it.

My code is quite simple :

while True:
    price = float(driver.find_elements_by_xpath("//td[@class='col-prix']")[0].text.strip()[:-1].replace(",","."))
    if a <= price <= b: break
    driver.find_elements_by_xpath("//button")[0].click()

and sometimes I get :

Traceback (most recent call last):
  File "script.py", line 51, in <module>
    driver.find_elements_by_xpath("//button")[0].click()

(...)

File "C:\Python\Python37-32\lib\site-packages\selenium-3.141.0-py3.7.egg\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

and sometimes :

Traceback (most recent call last):
  File "script.py", line 49, in <module>
    price = float(driver.find_elements_by_xpath("//td[@class='col-prix']")[0].text.strip()[:-1].replace(",","."))

(...)

  File "C:\Python\Python37-32\lib\site-packages\selenium-3.141.0-py3.7.egg\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

So I was interested in checking whether both are present (visible ???).

I tried to implement a simple :

wait = WebDriverWait(driver, 60)
element = wait.until(EC.presence_of_element_located((By.XPATH,"//button")))

and

wait = WebDriverWait(driver, 60)
element = wait.until(EC.presence_of_element_located((By.XPATH,"//td[@class='col-prix']")))

but I still get the same errors.

QUESTION # 1: am I using the correct syntax?

QUESTION # 2: can this be linked to the fact that both elements need to have a predicate [0] (and if yes how can I specify the predicate in the presence_of_element_located)?

Thanks for your help! ;-)


EDIT

Here's my code.

I have a setting file "test.txt" which only contains :

https://ticketplace.psg.fr/fr/recherche-place/668829,1,1:2:3:4:5:6:7:8:9:10:11:12:13:14:15,81,161

I have a .cmd file which only contains :

start "test" "py" "test.py" "test.txt"

and I have a test script "test.py" :

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from time import sleep
import datetime
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
import csv
import sys
from playsound import playsound
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

driver = webdriver.Chrome(executable_path="chromedriver")
with open(str(sys.argv[1]), "r") as settings:
    for setting in settings:
        driver.get(setting.split(",")[0].strip())
        tickets=setting.split(",")[1]
        categories=setting.split(",")[2]
        minPrice=float(setting.split(",")[3].strip())
        maxPrice=float(setting.split(",")[4].strip())
        try:
            driver.find_element_by_css_selector(".accepte_cookie.bandeau_close").click()
            alert = driver.switch_to.alert
            alert.accept()
            sleep(1)
        except:
            pass
        try:
            driver.find_elements_by_xpath("//button")[0].click()
            driver.find_element_by_xpath("//li[@data-search-term="+tickets+"]").click()
            driver.find_elements_by_xpath("//button")[0].click()
            sleep(1)
            driver.find_elements_by_xpath("//button")[1].click()
            for categorieNumber in categories.split(':'):
                driver.find_element_by_xpath("//li[@data-search-term='cat. "+categorieNumber+"']").click()
            driver.find_elements_by_xpath("//button")[1].click()
            sleep(1)
        except:
            continue
        while True:
            hint = float(driver.find_elements_by_xpath("//td[@class='col-prix']")[0].text.strip()[:-1].replace(",","."))
            if minPrice <= hint <= maxPrice: break
            driver.find_elements_by_xpath("//button")[0].click()
            driver.find_elements_by_xpath("//button")[0].click()
            sleep(1)
        cat = driver.find_elements_by_xpath("//td[@class='col-cat']")[0].text
        print(datetime.datetime.now().strftime("%H:%M")+" - "+tickets+" tix "+cat+" at "+str(int(hint)))
jeremoquai
  • 101
  • 2
  • 10
  • ```selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document``` means you need to assigned back your elements once you navigated from the page and back again – KunduK Feb 19 '19 at 12:23
  • 1
    If you could share your html.OP will get more clarity? – KunduK Feb 19 '19 at 12:24
  • @KajalKundu thanks but how do i do this : by calling driver.get ? – jeremoquai Feb 19 '19 at 12:25
  • 1
    If you could post the html the part you are getting problem it will be better to tell you the answer. – KunduK Feb 19 '19 at 12:27
  • sorry but what is the HTML part ? – jeremoquai Feb 19 '19 at 12:28
  • Html of the page you are currently stuck. – KunduK Feb 19 '19 at 12:33
  • as an example : https://ticketplace.psg.fr/fr/recherche-place/668829 – jeremoquai Feb 19 '19 at 12:36
  • @KajalKundu you have it all (but Moshe Slavin disappeared :-/ ) – jeremoquai Feb 19 '19 at 13:30
  • @KajalKundu yes i want to click on the "Nombre de billets" over and over again rather quickly because the next step is to be able to purchase a cheap ticket LOL ! clicking twice on "Nombre de billets" or "categorie" or on the price selector is the only way to refresh the results set with the tickets and their price – jeremoquai Feb 19 '19 at 13:45
  • Give me some time busy with something. – KunduK Feb 19 '19 at 14:01
  • no pb and thanks already for your help <3 – jeremoquai Feb 19 '19 at 14:01
  • PS : as you can see (and Moshe - he left - cannot see, too bad) the script DOES work with driver.find_elements_by_xpath("//button")[0].click() and DOESN'T with driver.find_elements_by_xpath("//button")[2].click() – jeremoquai Feb 19 '19 at 14:07

1 Answers1

1

Instead of this.

while True:
            hint = float(driver.find_elements_by_xpath("//td[@class='col-prix']")[0].text.strip()[:-1].replace(",","."))
            if minPrice <= hint <= maxPrice: break
            driver.find_elements_by_xpath("//button")[0].click()
            driver.find_elements_by_xpath("//button")[0].click()
            sleep(1)

Try the below code.

while True:
price = float(driver.find_elements_by_xpath("//td[@class='col-prix']")[0].text.strip()[:-1].replace(",", "."))
print(price)
if a <= price <= b: break
element=WebDriverWait(driver,5).until(EC.visibility_of_element_located((By.XPATH,"//button/span[text()='Tous les billets']")))
ActionChains(driver).move_to_element(element).perform()
driver.refresh()

Please let me know if it works.

KunduK
  • 32,888
  • 5
  • 17
  • 41
  • don't know about your min & max price you can set accordingly inside for loop.Hope this help you. – KunduK Feb 19 '19 at 14:15
  • the code does work but it does not CONTINUOUSLY check (in order to be able to hit a very low price, as an example) and that's what i wanted to achieve – jeremoquai Feb 19 '19 at 14:23
  • NB : min and max price were a and b – jeremoquai Feb 19 '19 at 14:24
  • the link which you have provided minimum price is 88 and that is printing right.How can you go beyond the limit. – KunduK Feb 19 '19 at 14:26
  • it continuously changes depending on the new listings and the other people buying tickets it's like the stock market – jeremoquai Feb 19 '19 at 14:27
  • selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//button/span[text()='Tous les billets']"} + you're still obliged to use sleep(2) and if the page takes more time to make its elements available, it's failing just like my initial script – jeremoquai Feb 19 '19 at 14:38
  • Its not failing here. – KunduK Feb 19 '19 at 14:41
  • i copied/pasted the error i got + once again my concern was to get rid of sleep to be quicker and to bear with latency in the availability of prices list – jeremoquai Feb 19 '19 at 14:42
  • It will check for presence of the element. – KunduK Feb 19 '19 at 14:46
  • I hope it helps you. – KunduK Feb 19 '19 at 14:47
  • sorry still failing here : File "test.py", line 50, in element=WebDriverWait(driver,5).until(EC.visibility_of_element_located((By.XPATH,"//button/span[text()='Tous les billets']"))) File "C:\Python\Python37-32\lib\site-packages\selenium-3.141.0-py3.7.egg\selenium\webdriver\support\wait.py", line 80, in until raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: – jeremoquai Feb 19 '19 at 15:04
  • Because of your internet slow.I can't help you buddy. – KunduK Feb 19 '19 at 15:05
  • mmmhhh don't think it is the case but thanks anyway for what you tried to achieve – jeremoquai Feb 19 '19 at 15:06
  • Yes.Sometimes you should appreciate OP effort.I consistently run in my machine not even failed once. – KunduK Feb 19 '19 at 15:10
  • maybe some kind of configuration problem which will also explain why button[0] is working for me although it shouldn't ? – jeremoquai Feb 19 '19 at 15:12
  • It is not best practice to use index when you have element xpath available.Good luck. – KunduK Feb 19 '19 at 15:15
  • I agree but for some reason if I copy/paste the XPath link provided when I inspect the element on Chrome, it doesn't work ! definitely something strange here with my configuration – jeremoquai Feb 19 '19 at 15:17