0
votes

I have a script that will open eBay and automate the buying process, and it works… for a while. After a series of loops, it randomly starts to skip sending data to text fields. The script will always runs perfectly the first time, but sporadically between the 2nd or 10th iteration,it will break; it hasn’t gotten past the 10th loop so far.

I'm using Python 2.7, Chrome 47 (with the chrome driver), and Selenium 2.53.5.

Here’s part of my code:

for o in orders:
if (o[1] == "Batteries"):
    driver.get("http://www.ebay.com/itm/20-Piece-Combo-Pack-Duracell-Duralock-10-AA-and-10-AAA-Size-Batteries-EXP-2025/272003416650?_trksid=p2045573.c100505.m3226&_trkparms=aid%3D555014%26algo%3DPL.DEFAULT%26ao%3D1%26asc%3D36866%26meid%3D1ff8810857444e0aa548e1aecb205110%26pid%3D100505%26rk%3D1%26rkt%3D1%26")

wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'qtyInput')))
input_field = driver.find_element_by_name('quantity')
input_field.clear()
input_field.send_keys(o[0])
driver.find_element_by_id('binBtn_btn').click()
#GUESTCHECKOUT
wait.until(EC.presence_of_element_located((By.ID, 'gtChk')))
driver.find_element_by_id('gtChk').click()

driver.switch_to_frame(driver.find_element_by_tag_name("iframe"))
wait.until(EC.presence_of_element_located((By.ID, 'confirmEmail')))

t = list(pycountry.countries)
for country in t:
    if(o[7] == country.alpha2):
        o[7] = country.name

Select(driver.find_element_by_name('country')).select_by_visible_text(o[7])
driver.find_element_by_name('firstName').send_keys(name[0])
driver.find_element_by_name('lastName').send_keys(o[2])

driver.find_element_by_name('address1').send_keys(o[3])

driver.find_element_by_name('city').send_keys(o[4])

Select(driver.find_element_by_name('state')).select_by_value(o[6])
driver.find_element_by_name('zip').send_keys(o[5])

driver.find_element_by_name('dayphone1').send_keys("123")
driver.find_element_by_name('dayphone2').send_keys("456")
driver.find_element_by_name('dayphone3').send_keys("7890")

driver.find_element_by_name('email').send_keys("[email protected]")
driver.find_element_by_name('confirmEmail').send_keys("[email protected]")

Traceback (most recent call last): File "autoBuyer.py", line 267, in driver.find_element_by_name('lastName').send_keys(name[1]) File "/Library/Python/2.7/site-packages/selenium-2.53.5-
py2.7.egg/selenium/webdriver/remote/webelement.py", line 321, in send_keys self._execute(Command.SEND_KEYS_TO_ELEMENT, {'value':
keys_to_typing(value)}) File "/Library/Python/2.7/site-packages/selenium-2.53.5-
py2.7.egg/selenium/webdriver/remote/webelement.py", line 456, in _execute return self._parent.execute(command, params) File "/Library/Python/2.7/site-packages/selenium-2.53.5- py2.7.egg/selenium/webdriver/remote/webdriver.py", line 236, in execute self.error_handler.check_response(response) File "/Library/Python/2.7/site-packages/selenium-2.53.5- py2.7.egg/selenium/webdriver/remote/errorhandler.py", line 194, 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 (Session info: chrome=51.0.2704.106) (Driver info: chromedriver=2.22.397929
(fb72fb249a903a0b1041ea71eb4c8b3fa0d9be5a),platform=Mac OS X 10.11.5 x86_64)

1
Can you include the exact error and stacktrace? - Levi Noecker
@LeviNoecker Just did! - orpheus

1 Answers

0
votes

StaleElementReferenceExceptions generally indicate the the DOM refreshed while you were interacting with the element. I commonly see them on highly dynamic webpages.

If the calls similar to driver.find_element_by_name('dayphone1').send_keys("123") are what seem to be throwing the exception the most, I would create a function to handle that specific type of call, and then decorate it with any of the @retry packages out there.

I can't run your code as written, but here is a demonstration of the changes I would make: (be sure to pip install retry first)

from retry import retry
from selenium.common.exceptions import StaleElementReferenceException

@retry(StaleElementReferenceException, tries=3)
def find_by_name_send_keys(driver, name_str, keys, clear=False):
    elem = driver.find_element_by_name(name_str)

    if clear:
        elem.clear()

    elem.send_keys(keys)


for o in orders:
if (o[1] == "Batteries"):
    driver.get("http://www.ebay.com/itm/20-Piece-Combo-Pack-Duracell-Duralock-10-AA-and-10-AAA-Size-Batteries-EXP-2025/272003416650?_trksid=p2045573.c100505.m3226&_trkparms=aid%3D555014%26algo%3DPL.DEFAULT%26ao%3D1%26asc%3D36866%26meid%3D1ff8810857444e0aa548e1aecb205110%26pid%3D100505%26rk%3D1%26rkt%3D1%26")

wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'qtyInput')))

find_by_name_send_keys(driver, 'quantity', o[0], clear=True)
driver.find_element_by_id('binBtn_btn').click()
#GUESTCHECKOUT
wait.until(EC.presence_of_element_located((By.ID, 'gtChk')))
driver.find_element_by_id('gtChk').click()

driver.switch_to_frame(driver.find_element_by_tag_name("iframe"))
wait.until(EC.presence_of_element_located((By.ID, 'confirmEmail')))

t = list(pycountry.countries)
for country in t:
    if(o[7] == country.alpha2):
        o[7] = country.name

Select(driver.find_element_by_name('country')).select_by_visible_text(o[7])
find_by_name_send_keys(driver, 'firstName', name[0])
find_by_name_send_keys(driver, 'lastName', o[2])

find_by_name_send_keys(driver, 'address1', o[3])

find_by_name_send_keys(driver, 'city', o[4])

Select(driver.find_element_by_name('state')).select_by_value(o[6])
find_by_name_send_keys(driver, 'zip', o[5])

find_by_name_send_keys(driver, 'dayphone1', "123")
find_by_name_send_keys(driver, 'dayphone2', "456")
find_by_name_send_keys(driver, 'dayphone3', "7890")

find_by_name_send_keys(driver, 'email', "[email protected]")
find_by_name_send_keys(driver, 'confirmEmail', "[email protected]")