我有一个脚本可以打开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的)
答案 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")