![](/img/trans.png)
[英]Stale element reference: element is not attached to the page document when looping through pages
[英]Element Not Attached to page document when iterating through web elements
我正在尝试迭代点击优步运动数据中的北美城市。
我已将 Python 代码设置为 select 所有城市的表(cities_table),将其放入列表中,并确定要单击的每个城市的按钮(该按钮的标签名称为“a”)。
我的问题是我能够 select 表中的第一个城市(亚特兰大),但是当我尝试 go 回到包含所有城市表的页面时,我无法点击列表中的下一个城市,这应该是波士顿。
成功进入亚特兰大页面后,我将 driver.back() 设置为 go 回到城市表,但是当尝试转到列表中的下一项时,我收到以下错误消息:
Message: stale element reference: element is not attached to the page document
我怎样才能正确点击一个城市,go 回到城市表页面并点击 NEXT 项?
到目前为止,这是我的代码:
# Load Chrome driver and movement.uber.com/cities website
PATH = 'C:\Program Files (x86)\chromedriver.exe'
driver = webdriver.Chrome(PATH)
driver.get('https://movement.uber.com/cities?lang=en-US')
# City loop
cities_table = driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[1]/div[2]/div[1]/div')
cities = cities_table.find_elements_by_tag_name('div')
for city in cities:
city = city.find_element_by_tag_name('a') # Buttons have tags "a"
city.click()
time.sleep(3)
driver.back()
完整的错误信息如下:
StaleElementReferenceException Traceback (most recent call last)
<ipython-input-25-a148ef184a6b> in <module>
6 cities = cities_table.find_elements_by_tag_name('div')
7 for city in cities:
----> 8 city = city.find_element_by_tag_name('a') # Buttons have tags "a"
9 city.click()
10 time.sleep(3)
~\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\remote\webelement.py in find_element_by_tag_name(self, name)
303 element = element.find_element_by_tag_name('h1')
304 """
--> 305 return self.find_element(by=By.TAG_NAME, value=name)
306
307 def find_elements_by_tag_name(self, name):
~\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\remote\webelement.py in find_element(self, by, value)
657
658 return self._execute(Command.FIND_CHILD_ELEMENT,
--> 659 {"using": by, "value": value})['value']
660
661 def find_elements(self, by=By.ID, value=None):
~\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\remote\webelement.py in _execute(self, command, params)
631 params = {}
632 params['id'] = self._id
--> 633 return self._parent.execute(command, params)
634
635 def find_element(self, by=By.ID, value=None):
~\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params)
319 response = self.command_executor.execute(driver_command, params)
320 if response:
--> 321 self.error_handler.check_response(response)
322 response['value'] = self._unwrap_value(
323 response.get('value', None))
~\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response)
240 alert_text = value['alert'].get('text')
241 raise exception_class(message, screen, stacktrace, alert_text)
--> 242 raise exception_class(message, screen, stacktrace)
243
244 def _value_or_default(self, obj, key, default):
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=84.0.4147.89)
发生此错误是因为您正在获取不再存在的 dom 元素的引用。 每次重新加载或刷新页面,或者 dom 发生了一些变化,你之前获得的每一个引用都是无用的。
因此,为了工作,您必须保留已处理内容的引用,并在每次页面更改时更新您的 dom 引用。
# City loop
managed_cities = []
while True:
cities_table = driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[1]/div[2]/div[1]/div')
cities = cities_table.find_elements_by_tag_name('div')
for city in cities:
# Here you have to find and ID or some unique text that identifies the
# already processed city in order to skip it
if city.text in managed_cities:
continue
city = city.find_element_by_tag_name('a') # Buttons have tags "a"
city.click()
time.sleep(3)
driver.back()
break
# Now, if you have managed all the cities, you can exit from the while
# otherwise, keep loop until all cities have been processed
if len(managed_cities) == len(cities):
break
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.