python selenium'send_keys'不能始终如一地运作

时间:2016-06-30 20:23:59

标签: python loops selenium crash

我有一个脚本可以打开eBay并自动完成购买过程,它可以运行一段时间。在一系列循环之后,它随机开始跳过将数据发送到文本字段。脚本将始终在第一次完美运行,但偶尔会在第2次或第10次迭代之间运行,它会中断;到目前为止,它还没有超过第10个循环。

我使用的是Python 2.7,Chrome 47(使用Chrome驱动程序)和Selenium 2.53.5。

这是我的代码的一部分:

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("d@gmail.com")
driver.find_element_by_name('confirmEmail').send_keys("d@gmail.com")
  

Traceback(最近一次调用最后一次):文件“autoBuyer.py”,第267行,in    driver.find_element_by_name( 'lastName的')。send_keys(名称[1])   文件“/Library/Python/2.7/site-packages/selenium-2.53.5-
  py2.7.egg / selenium / webdriver / remote / webelement.py“,第321行,in   send_keys self._execute(Command.SEND_KEYS_TO_ELEMENT,{'value':
  keys_to_typing(value)})文件   “/Library/Python/2.7/site-packages/selenium-2.53.5-
  py2.7.egg / selenium / webdriver / remote / webelement.py“,第456行,in   _execute返回self._parent.execute(command,params)文件“/Library/Python/2.7/site-packages/selenium-2.53.5-   py2.7.egg / selenium / webdriver / remote / webdriver.py“,第236行,in   执行self.error_handler.check_response(响应)文件   “/Library/Python/2.7/site-packages/selenium-2.53.5-   py2.7.egg / selenium / webdriver / remote / errorhandler.py“,第194行,中   check_response       raise exception_class(message,screen,stacktrace)selenium.common.exceptions.StaleElementReferenceException:Message:   陈旧元素引用:元素未附加到页面   document(会议信息:chrome = 51.0.2704.106)(驱动程序信息:   chromedriver = 2.22.397929
  (fb72fb249a903a0b1041ea71eb4c8b3fa0d9be5a),platform = Mac OS X 10.11.5   x86_64的)

1 个答案:

答案 0 :(得分:0)

StaleElementReferenceException通常表示在与元素交互时刷新了DOM。我经常在高度动态的网页上看到它们。

如果类似于driver.find_element_by_name('dayphone1').send_keys("123")的调用似乎最多抛出异常,我会创建一个函数来处理该特定类型的调用,然后使用@retry中的任何一个来装饰它打包那里。

我无法按照编写的方式运行您的代码,但这是对我所做的更改的演示: (务必先pip install retry

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', "d@gmail.com")
find_by_name_send_keys(driver, 'confirmEmail', "d@gmail.com")