#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))