Python Selenium. Проблема
Всем доброго времени суток. Пишу бота для Инстаграмма, который будет комментить выбранный пост, но в момент поста появляется ошибка
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: chrome=86.0.4240.198)
Ну а вот собственно код Ошибка появляется когда должен начаться цикл Ypffh это таг где место под комментарий в посте
from time import sleep
from selenium import webdriver
from auth_data import username, password
from selenium.webdriver.common.keys import Keys
from target_coms import tar_com
print('Preparing! Let me know some things, enter it below this messege')
sleep(3)
tar_url = input('Enter Target url: ')
print('Thx, hope url doesnt wrong, we start soon')
sleep(3)
def auth():
browser = webdriver.Chrome('Chrome/chromedriver.exe')
browser.implicitly_wait(5)
browser.get('https://instagram.com')
username_input = browser.find_element_by_name('username')
username_input.clear()
username_input.send_keys(username)
sleep(2)
password_input = browser.find_element_by_name('password')
password_input.clear()
password_input.send_keys(password)
sleep(2)
login_link = browser.find_element_by_xpath("//button[@type='submit']")
login_link.click()
sleep(5)
browser.get(tar_url)
sleep(5)
for i in range(1, 5):
comments_put = browser.find_element_by_class_name('Ypffh')
comments_put.click()
comments_put.send_keys(tar_com + str(i))
comments_put.send_keys(Keys.ENTER)
sleep(2)
sleep(10)
browser.close()
auth()
Ответы (1 шт):
Это частая ошибка, когда вы пытаетесь работать с интерактивными элементами (особенно, когда это генерируемые на лету элементы). Суть ситуации в следующем: когда элемент создается с помощью JS, сперва он просто создается в документе, а потом приаттачевается в DOM к определенному узлу. Ошибка, которую вы получаете, указывает на то, что вы обратились к элементу в момент, когда операции с ним еще не были завершены и он не готов к работе - не приаттачен к узлу дерева DOM.
Обойти этот момент можно несколькими способами:
установив харкодный
time.sleepна 0,5-3 секунды перед обращением к элементу. Обычно этого достаточно.Использовать встроенные механизмы ожидания (WebDriverWait и implicitly_wait; последний используется в вашем случае). Однако, они меня в моих проектах почему-то периодически подводят, поэтому я для себя решил использовать следующий способ.
Собственные ожидающие функции. Их структура достаточно простая. Нужно всего лишь в цикле проверять доступность элемента. В случае ошибки - продолжать ожидание, в случае успеха - выходить из цикла. Одним из достоинств этого метода может служить возможность добавления в такую функцию дополнительных операций (например промежуточного логирования и проверок) в процессе ожидания.
Примерный вариант реализации:
def get_element_when_ready(selector):
while True:
try:
element = browser.find_element_by_css_selector(selector)
except:
pass
else:
break
return element
elem = get_element_when_ready('.password')