#python-3.x #selenium
Вопрос:
Я пытаюсь просмотреть все страницы веб-сайта. но я получаю устаревшую ссылку на элемент: элемент не прикреплен к ошибке документа страницы. Это происходит, когда скрипт пытается перейти на третью страницу. Сценарий получил ошибку при запуске на страницу.нажмите(). Есть какие-нибудь предложения?
while driver.find_element_by_id('jsGrid_vgAllCases').find_elements_by_tag_name('a')[-1].text=='...':
links=driver.find_element_by_id('jsGrid_vgAllCases').find_elements_by_tag_name('a')
for link in links:
if ((link.text !='...') and (link.text !='ADD DOCUMENTS')):
print('Page Number: ' link.text)
print('Page Position: ' str(links.index(link)))
position=links.index(link)
page=driver.find_element_by_id('jsGrid_vgAllCases').find_elements_by_tag_name('a')[position]
page.click()
time.sleep(5)
driver.find_element_by_id('jsGrid_vgAllCases').find_elements_by_tag_name('a')[-1].click()
Комментарии:
1. Можете ли вы поделиться URL-адресом или источником HTML?
2. после вашего щелчка() DOM, вероятно, обновляется. Это приводит к тому, что каждый вызов метода после этого выбрасывает устаревший элемент. (Потому что ссылки, которые у вас есть, больше не действительны после обновления DOM.) В зависимости от ваших потребностей, вы можете просмотреть и получить ссылки. Затем используйте эти ссылки в цикле с помощью driver.get()s. На некоторых сайтах, которые могут не работать (если вы не можете добавлять ссылки в закладки…), поэтому вам придется сгладить.
Ответ №1:
Вы можете каждый раз находить элемент ссылки в соответствии с индексом, чтобы не использовать элементы, найденные изначально.
Что-то вроде этого:
amount = len(driver.find_element_by_id('jsGrid_vgAllCases').find_elements_by_tag_name('a'))
for i in range(1,amount 1):
link = driver.find_element_by_xpath("(//*[@id='jsGrid_vgAllCases']//a)[" str(i) "]")
с этого момента вы можете продолжать в своем цикле for link
вот так:
amount = len(driver.find_element_by_id('jsGrid_vgAllCases').find_elements_by_tag_name('a'))
for i in range(1,amount 1):
link = driver.find_element_by_xpath("(//*[@id='jsGrid_vgAllCases']//a)[" str(i) "]")
if ((link.text !='...') and (link.text !='ADD DOCUMENTS')):
print('Page Number: ' link.text)
print('Page Position: ' str(links.index(link)))
position=links.index(link)
page=driver.find_element_by_id('jsGrid_vgAllCases').find_elements_by_tag_name('a')[position]
page.click()
time.sleep(5)
(Я не уверен в правильности всего остального вашего кода, просто скопировал его и вставил)
Комментарии:
1. Я использую следующий код для перемещения ссылки, почему она не работает? страница=драйвер.идентификатор find_element_by_id(‘jsGrid_vgAllCases’).имя тега find_elements_by_tag_name(‘a’)[позиция]
2. Это действительно работает, он получает веб — элемент из списка, который вы собрали в начале, но так как вы перешли на другую страницу или страница была обновлена и т. Д. — Я понятия не имею, что именно там находится, — но страница была изменена, поэтому ранее полученные ссылки больше не указывали на эти элементы, так как элементы были изменены. В этом и заключается значение ошибки Устаревшего элемента. Вот почему вам нужно снова получить элементы, чтобы получить ссылку на существующий в данный момент элемент
Ответ №2:
У меня тоже возникла проблема с исключением Устаревшего элемента. Интересно, что с Firefox нет проблем, Chrome и Edge выходят из строя случайным образом. В общем, у меня есть два общих метода поиска с логикой повторных попыток, эти методы поиска будут выглядеть так:
// Yes C# but should be relevant for any WebDriver...
public static IWebElement( this IWebDriver driver, By locator)
public static IWebElement( this IWebElement element, By locator)
Вариант веб-драйвера, похоже, отлично подходит для моих других запросов, так как поиск всегда «свежий»… Но поиск веб-элементов-это то, что вызывает горе. К сожалению, приложение вынуждает меня использовать версию WebElement. Почему его страница/html будет чем-то вроде:
<node id='Best closest ID Possible'>
<span>
<div>text i want</div>
<div>meh ignore this </div>
<div>More text i want</div>
</span>
<span>
<!-- same pattern ... -->
Таким образом, код получает максимально близкий элемент по идентификатору и дочерним диапазонам, т. е. «//*[@id=’…’]/span» даст все узлы, представляющие интерес. Сейчас я сталкиваюсь с проблемами, перечисляя все элементы, я выполняю два выбора XPath, т. е. «./div[1]» и «./div[3]» для извлечения нужного текста. Это происходит только при извлечении текстовых узлов под элементами, где случайным образом будет брошен элемент StaleElement. Иногда самый первый XPath терпит неудачу, иногда я просматриваю несколько страниц, так как на страницах может быть 10 000 или более страниц, в то время как структура одинакова, я буду проверять случайные страницы, так как все они имеют одинаковый формат. Самое большее, я просмотрел 20 последовательных страниц с Chrome (версия 92.0.4515.107) или Edge (версия 94.0.986), оба, похоже, являются последними на данный момент.
Одно из решений, которое должно сработать, сначала получить все элементы span, т. Е. » //*[@id=’x’]/span», получить мой список, а затем запросить у драйвера, например:
var nodeList = driver.FindElements(By.XPath('//*[@id='x']/span' ));
for( int idx = 0 ; idx < nodeList.Count; idx )
{
string str1 = driver.FindElements(By.XPath("//*[@id='x']/span[idx 1]/div[1]")).GetAttribute("innerText");
string str2 = driver.FindElements(By.XPath("//*[@id='x']/span[idx 1]/div[3]")).GetAttribute("innerText");
}
```
Think it would work but, YUK! This is kind of simplified and being able to do an XPath from the respective "ID" located node would be preferable..