Reputation: 101
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)))
Upvotes: 0
Views: 214
Reputation: 33384
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.
Upvotes: 1