繁体   English   中英

遍历 web 元素时,元素未附加到页面文档

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM