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.
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)
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.
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.
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.
@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 ama olsun, çıkan hatalar ve onları çözmeye çalışmak selenium'da az da olsa bilgi edinmemi sağladı.