Почему я получаю StaleElementReferenceException, когда я «читаю» текстовое содержимое столбца? - PullRequest
1 голос
/ 19 мая 2019

Проблема возникает только тогда, когда я пытаюсь собрать ("сканировать") содержимое таблицы дважды. Первый раз, когда я читаю содержимое таблицы, успешно, но во второй раз всегда происходит сбой.

Это происходит только с браузером Chrome (версия 74 с соответствующим хром-драйвером). Я попробовал то же самое с FireFox, и это никогда не происходит. Я нашел определенный обходной путь в Chrome, который не имеет никакого смысла, но он делает свою работу.

Когда я "перехожу" на другой экран, кроме того, который включает таблицу, а затем возвращаюсь назад, сканирование таблицы успешно завершается.

Ниже приведена функция, которую я использую для сбора таблицы:

def Get_Faults_List(Port_Number=None, PSU=None, Retries=5):
    for attempt in range(Retries):
        try:
            if Port_Number:
                # Show the Faults view in the context of "Port_Number"
                Device_Panel_Frame.Click_Port(self, Port_Number)
            elif PSU:
                if not Device_Panel_Frame.Click_PSU(self, PSU):
                    return None
            Left_Panel_Frame.Click_Fault(self)

            self.driver.switch_to_default_content()
            Main_Body = self.driver.find_element_by_name('main_page')
            self.driver.switch_to.frame(Main_Body)
            alarms_tab = self.driver.find_element_by_id('tab_alarms')
            alarms_tab.click()
            Fault_Screen = self.driver.find_element_by_name('faults')
            self.driver.switch_to.frame(Fault_Screen)
            # the rows that the following variable collect are automatically
            # the relevant fault lines. The XPATH that was used omits the two
            # irrelevant lines
            faultTable_rows = WebDriverWait(self.driver, timeout=3, poll_frequency=0.5).until(
                EC.presence_of_all_elements_located((By.XPATH, "//table[@id='faultTab']//tr[not(@id or @style)]")))

            current_faults = []
            row_index = 0
            for row in faultTable_rows:  # Go through each of the rows
                current_faults.append([])
                # Collect all the column elements of a certain row into a list
                faultTable_row_cols = row.find_elements_by_tag_name("td")
                for col in faultTable_row_cols:
                    # Each row of the Faults table is separated into 5 columns each column holds a string
                    current_faults[row_index].append(col.text)
                row_index += 1

            break
        except:
            print(attempt + 1, 'attempt failed', Retries - (attempt + 1), 'to go')
            self.Refresh_Screen()
            sleep(5)
            continue

Мне удастся собрать содержимое таблицы также, если я открою новый браузер. Кстати, сбой всегда происходит в первой строке (после заголовка) следующей таблицы. Линия current_faults[row_index].append(col.text), и я не понимаю, почему. Исключение не имеет никакого смысла.

Есть ли другой способ эффективного сканирования содержимого таблицы?

Таблица: enter image description here

1 Ответ

1 голос
/ 26 мая 2019

См. этот ответ по той причине, что вы получаете Stale Element Reference Exception.

A Исключение ссылки на устаревший элемент возникает, когда элемент:

  1. Был удален
  2. Больше не подключен к DOM (как в вашем случае)
  3. Изменился

Из документов:

Вам следует отменить текущую ссылку, которую вы держите, и заменить ее, возможно, снова найдя элемент после его подключения к DOM.

т.е.: "Найти" элемент снова.

Мое предложение состоит в том, чтобы захватить HTML и выполнить цикл по нему:

Вы можете использовать driver.page_source, затем BeautifulSoup как таковое:

html = driver.page_source
soup = BeautifulSoup(html, "lxml")

Это должно быть реализовано после переключения кадров.

Надеюсь, это поможет вам!

...