Как мне справиться с «Сообщением: устаревшая ссылка на элемент: элемент не прикреплен к документу страницы» в Python Selenium

#python #python-3.x #selenium #selenium-webdriver #selenium-chromedriver

#python #python-3.x #селен #selenium-webdriver #selenium-chromedriver

Вопрос:

Я пишу скрипт для удаления названий продуктов с веб-сайта, отфильтрованных по брендам. Некоторые результаты поиска могут содержать более одной страницы, и именно здесь возникает проблема. Я могу очистить первую страницу, но когда скрипт нажимает на следующую страницу, появляется сообщение об ошибке selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document . Ниже приведен мой код:

 def scrape():
   resultList = []
   currentPage = 1

   while currentPage <= 2:
      titleResults = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'h4.mt-0')))
      resultList.append(titleResults)
      checkNextPage = WebDriverWait(driver, 30).until(EC.visibility_of_all_elements_located((By.XPATH, "//div/nav/ul/li/a[@aria-label='Next']")))
      for cnp in checkNextPage:
         nextPageNumber = int(cnp.get_attribute("data-page"))
      currentPage  = 1
      driver.find_element_by_xpath("//div/nav/ul/li/a[@aria-label='Next']").click()
   for result in resultList[0]:
      print("Result: {}".format(result.text))
  

Я думаю, что ошибка была вызвана при .click() вызове. Я много искал в Интернете, прежде чем опубликовать этот вопрос здесь, потому что либо я не понимаю решения из других статей / сообщений, либо они не применимы к моему случаю.

Комментарии:

1. Не уверен на 100%, что это проблема, но не могли бы вы попробовать добавить titleResults.text вместо titleResults? Дело в том, что resultList содержит список веб-элементов, прикрепленных к первой странице, но после щелчка элементы становятся «устаревшими», потому что страница изменилась, поэтому элементы больше не прикреплены к документу страницы, и вы не можете распечатать текст результатов. Если вы добавляете текст вместо веб-элемента, тот факт, что веб-страница изменилась, не имеет значения, поэтому она должна работать.

2. проблема в том, что видимость всех элементов возвращается, если найден хотя бы 1 элемент. Он не знает, сколько элементов может стать присутствующим или видимым. Таким образом, DOM все еще может обновляться. (В вашем коде устаревший элемент будет выдаваться при использовании cnp.get_attribute) Следующие кнопки> 1? Лучшее, что можно сделать, это активировать вызов драйвера и попытаться / перехватить исключение устаревшего элемента… если он пойман, попробуйте еще раз (функция повторного вызова). Используйте счетчик в качестве проверки работоспособности … если счетчик = 2 * Время ожидания WebDriverWait, не вызывайте повторно. (WebDriverWait опрашивает с интервалом в 1/2 секунды и выдает тайм-аут или StaleElement)

3. в качестве альтернативы просто добавьте режим ожидания перед получением массива checkNextPage.

Ответ №1:

Устаревший элемент означает старый элемент или более недоступный элемент.

Я думаю, что ошибка вызвана последней строкой.

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

 def scrape():
   resultList = []
   currentPage = 1

   while currentPage <= 2:
      titleResults = WebDriverWait(driver, 
10).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'h4.mt-0')))

      // Extract elements text 
      results_text = [titleResults[i].text for i in range(0, len(titleResults))]
      resultList.extend(results_text)

      checkNextPage = WebDriverWait(driver, 30).until(EC.visibility_of_all_elements_located((By.XPATH, "//div/nav/ul/li/a[@aria-label='Next']")))
      for cnp in checkNextPage:
         nextPageNumber = int(cnp.get_attribute("data-page"))
      currentPage  = 1
      driver.find_element_by_xpath("//div/nav/ul/li/a[@aria-label='Next']").click()


  print("Result: {}".format(resultList))