Python Selenium StaleElementReferenceException

Merhaba, işlerimi hızlandırmak için bir bot yazıyorum. Geliştirme sırasında ilginç bir problem ile karşılaştım. Kodlar bazen hata veriyor bazen vermiyor.

Kodlar düzgün çalıştığında :


Kodlar hata verdiğinde :

Log in kısmını kırpmam gerekti.Yardımcı olursanız sevinirm, teşekkürler.

Hata kısmını tam olarak atarmısınız ?

1 Beğeni

Kodları paylaşmayı unutmuşum.

# -*- coding:utf-8 -*-

from selenium import webdriver

class Bot():
	def __init__(self):
		self.browser = webdriver.Chrome(executable_path="C:/Users/User/Desktop/n11Bot/driver/chromedriver")
		self.browser.get("https://so.n11.com/")
		self.giris_yap()

	def giris_yap(self):
		self.browser.implicitly_wait(1)

		self.kullaniciAdi = self.browser.find_element_by_name("j_username")
		self.kullaniciAdi.send_keys("kullaniciAdi")
		self.parola = self.browser.find_element_by_name("j_password")
		self.parola.send_keys("parola")
		self.girisYapButonu = self.browser.find_element_by_id("j_id44_j_id_2e").click()

		self.urun_ekle()

	def urun_ekle(self):
		self.browser.implicitly_wait(1)
		# Ürün yönetimi
		self.urunYonetimi = self.browser.find_element_by_css_selector("#menuContainer > div > div:nth-child(2) > div.text").click()
		# Ürün ekle
		self.urunEkle = self.browser.find_element_by_link_text("Yeni Ürün Ekle").click()
		self.browser.implicitly_wait(3)
		# Seçin
		self.kategori1 = self.browser.find_element_by_id("categorySelectionTabs:categorySelector:categoryGroupSelectOneMenu_label").click()
		self.browser.implicitly_wait(1)
		# Ev & Yaşam
		self.kategori2 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:categoryGroupSelectOneMenu_panel > div > ul > li:nth-child(4)").click()
		self.browser.implicitly_wait(1)
		# Kırtasiye & Ofis
		self.kategori3 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:categoryLevel1 > ul > li:nth-child(8)").click()
		self.browser.implicitly_wait(1)
		# Ofis Kırtasiye
		self.kategori4 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:j_id_55 > ul > li:nth-child(2)").click()
		self.browser.implicitly_wait(1)
		# Delgeç
		self.kategori5 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:j_id_59 > ul > li:nth-child(2)").click()
		# Devam
		self.devam = self.browser.find_element_by_id("j_id140_j_id_5n").click()


if __name__ == "__main__":
	calistir = Bot()
```

Buyrun:

Traceback (most recent call last):
  File "n11Bot.py", line 47, in <module>
    run = Bot()
  File "n11Bot.py", line 9, in __init__
    self.login()
  File "n11Bot.py", line 19, in login
    self.add_product()
  File "n11Bot.py", line 35, in add_product
    self.category3 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:categoryLevel1 > ul > li:nth-child(8)").click()
  File "C:\Users\User\Desktop\n11Bot\venv\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
    self._execute(Command.CLICK_ELEMENT)
  File "C:\Users\User\Desktop\n11Bot\venv\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "C:\Users\User\Desktop\n11Bot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\User\Desktop\n11Bot\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=83.0.4103.116)
  (Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 6.1.7601 SP1 x86_64)

Bazen bu hatanın dışında da hatalar veriyor. Element bulamama gibi, WebDriverException gibi.

Web sitesi isimleri değişiyor olabilir.
Xpath ile denedinizmi ?

Daha önce de XPath yerine CSS selektörleri kullanılması gerektiğini söylemiştim. Elementler değişiyorsa XPath nasıl sabit kalacak acaba?

Web sitesinin elementlerin isimlerini değiştirmesi, elementlerin XPath’ını değiştirmesi yanında çok düşük bir olasılık. Böyle bir değişim olduğundan emin olunduktan sonra XPath bir alternatif olabilir.

1 Beğeni

Bu kısmı göremediğim için birşey diyemem ama diğer find_element'leri deneyebilirsiniz.
Burada bir kısmı bulunuyor.

Kullanıcı paneli olduğu için HTML kodlarını sizlerle paylaşamıyorum. Bunun, bana yardımcı olmanızı ciddi anlamda engellediğinin farkındayım. O yüzden elimden geleni yapıyor, yardımcı olabilmeniz için size bir kapı açmaya çalışıyorum.

ActionChains sınıfını kullandım. Kodlar daha sağlıklı çalışıyor. Artık hiç hata vermiyor.
Kodların son hali:

# -*- coding:utf-8 -*-

from selenium import webdriver
from selenium.common.exceptions import (NoSuchElementException, StaleElementReferenceException)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions

class Bot():
	def __init__(self):
		self.browser = webdriver.Firefox(executable_path="C:/Users/User/Desktop/n11Bot/driver/geckodriver")
		self.browser.get("https://so.n11.com/")
		self.giris_yap()

	def giris_yap(self):
		self.browser.implicitly_wait(1)

		self.kullaniciAdi = self.browser.find_element_by_name("j_username")
		self.kullaniciAdi.send_keys("username")
		self.parola = self.browser.find_element_by_name("j_password")
		self.parola.send_keys("password")
		self.girisYapButonu = self.browser.find_element_by_id("j_id44_j_id_2e").click()

		self.urun_ekle()

	def urun_ekle(self):
		self.browser.implicitly_wait(1)
		# Ürün yönetimi
		self.urunYonetimi = self.browser.find_element_by_css_selector("#menuContainer > div > div:nth-child(2) > div.text")
		# Ürün ekle
		self.urunEkle = self.browser.find_element_by_css_selector("#menuContainer > div > div:nth-child(2) > div.submenu > ul > li:nth-child(2) > a")
		self.browser.implicitly_wait(3)

		ActionChains(self.browser).move_to_element(self.urunYonetimi).click().move_to_element(self.urunEkle).click().perform()
		# Seçin
		self.kategori1 = self.browser.find_element_by_id("categorySelectionTabs:categorySelector:categoryGroupSelectOneMenu_label")
		self.browser.implicitly_wait(1)
		# Ev & Yaşam
		self.kategori2 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:categoryGroupSelectOneMenu_panel > div > ul > li:nth-child(4)")
		self.browser.implicitly_wait(1)
		ActionChains(self.browser).move_to_element(self.kategori1).click().move_to_element(self.kategori2).click().perform()
		# Kırtasiye & Ofis
		self.kategori3 = self.browser.find_element_by_css_selector("li.ui-selectlistbox-item:nth-child(8)")
		self.browser.implicitly_wait(1)
		self.scroll = self.browser.execute_script("arguments[0].scrollIntoView(true);", self.kategori3)
		if self.scroll:
			print("Bulundu!")
		else:
			print("Bulunamadi")
		# ActionChains(self.browser).move_to_element(self.kategori3).click().perform()
		# Ofis Kırtasiye
		# self.kategori4 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:j_id_55 > ul > li:nth-child(2)")
		# self.browser.implicitly_wait(1)
		# # Delgeç
		# self.kategori5 = self.browser.find_element_by_css_selector("#categorySelectionTabs\:categorySelector\:j_id_59 > ul > li:nth-child(2)").click()
		# # Devam
		# self.devam = self.browser.find_element_by_id("j_id140_j_id_5n").click()


if __name__ == "__main__":
	calistir = Bot()

Ancak hala bir problem mevcut. ActionChains ilgili elementi görmüyor. Scroll’u aşağı indirip, elementi(kategoriyi) görmesini sağlamalıyız. Kodlar hata vermiyor ama scroll’u da aşağı indirmiyor. Sayfa scroll’unu değil, kategorilerin olduğu kutucuğun scroll’unu aşağı indirmeliyiz.

Burada takıldım, ilerleyemiyorum. İnternette çok fazla örnek var ama hepsi de sayfayı kaydırma ile ilgili.

Bu problemi atlatırsak sonrasını rahatlıkla yapabileceğimi düşünüyorum. Yardımcı olursanız sevinirim.

Kaydırma çubuğunu kaydırmadan şeçmeyi denedinizmi ?

Evet, ActionChains ile denediğimde tepki vermiyor. Normal olarak direkt click() kullanınca da ElementClickInterceptedException hatası veriyor. StackOverflow'da “Söz konusu elementi başka bir element gizlediği için tıklanamıyor” denilmiş. WebdriverWait kullandım, bu kez de InvalidArgumentException hatası verdi.

Bunu yapabilen örnek kod bulamadım.

Onu oluşturan elementi bulun ve ilgili kutuyu seçemezmisiniz ?
Birde sayfanın kaynak kodunu fotoğraf olarak atarmısınız ?
Özellikle scroll kısmını.

@Wormer_King ilgilendiğiniz için teşekkürler.
Aklıma gelen bütün yöntemleri denedim. Dökümanı sömürdüm ama olmadı. Az önce n11’in API desteklediğini öğrendim. Biraz geç keşfettim :smiley: ama olsun, çıkan hatalar ve onları çözmeye çalışmak selenium'da az da olsa bilgi edinmemi sağladı.

1 Beğeni