Python Selenium ile döngü oluştururken hata

Katılım
25 Aralık 2021
Mesajlar
648
Çözümler
1
Daha fazla  
Cinsiyet
Erkek
Bir bot yapmaya çalışıyorum. Botun mantığı şu;
  1. Bir input var önce bu inputa marka girip enter işlevi yaptırıyorum.
  2. Sonra model inputu yükleniyor ve modeli giriyorum, tekrar enter işlevi sonrasında bir tablo yükleniyor ve tabloda bu marka model için içerikler çıkıyor.
  3. Bu içerikleri Excel'e yazdırıp sonrasında model inputuna tekrardan aynı marka için bir diğer modeli girmek istediğimde stale element not found hatası alıyorum.
  4. Hatayı biraz araştırdım ve sayfanın yenilendiğini ve yenilenen elementlere aynı CSS özellikleri ile (ID, class ismi gibi) erişmeye çalışırken hata alınabileceğini söylüyor ancak çözümünü de bulamadım. Ben döngü ile elimdeki marka modele göre arama yaptırmak ve çıkan değerleri Excel'e kaydettirmek istiyorum.
  5. Elimdeki marka modelden kastım da aslında bu inputların içerisinde select elementi gibi bir sürü veri var. Önce o verileri alıyorum, sonra tek tek aratıyorum.

Var mı bir fikriniz? Kodlar evdeki PC'de kaldığı için atamadım ama çok gerekli olursa atarım geçince. Çok teşekkür ederim şimdiden.
 
Merhaba,

Stale Element hatası genellikle bir önceki sayfanın elemanlarının güncellenmiş olması veya belirli bir süre sonra sayfanın yeniden yüklendiği durumlarda ortaya çıkar.

Wait Explicitly Sayfanın güncellenmesini bekleyebilirsin. Selenium'da WebDriverWait kullanarak belirli bir elemanın belirli bir duruma ulaşmasını bekleyebilirsin.

Python:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver, 10) # 10 saniye bekleyecek
element = wait.until(EC.element_to_be_clickable((By.ID, 'element_id')))

başka bir seçenek olarak,

Stale element hatası aldığında, sayfayı yenileyerek yeniden yükleyebilirsin.

Python:
driver.refresh()

eğer bu yukarıda yazdığım ikisi sorunu çözmezse bunuda deneyebilirsin.

Stale element hatası aldığında, elemanı yeniden bulabilirsin. Bu, elemanın güncellenmiş bir referansa sahip olmasını sağlar.

Python:
element = driver.find_element_by_id('element_id')

eğer bu verdiklerim işine yaramaz ise,

elemana erişmek için kullanılan CSS selector veya XPath hala geçerliyse, bunları kullanabilirsin. Bazı durumlarda, farklı bir seçici kullanmak hata almanı önleyebilir.
 
Merhaba,

Stale Element hatası genellikle bir önceki sayfanın elemanlarının güncellenmiş olması veya belirli bir süre sonra sayfanın yeniden yüklendiği durumlarda ortaya çıkar.

Wait Explicitly Sayfanın güncellenmesini bekleyebilirsin. Selenium'da WebDriverWait kullanarak belirli bir elemanın belirli bir duruma ulaşmasını bekleyebilirsin.

Python:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver, 10) # 10 saniye bekleyecek
element = wait.until(EC.element_to_be_clickable((By.ID, 'element_id')))

başka bir seçenek olarak,

Stale element hatası aldığında, sayfayı yenileyerek yeniden yükleyebilirsin.

Python:
driver.refresh()

eğer bu yukarıda yazdığım ikisi sorunu çözmezse bunuda deneyebilirsin.

Stale element hatası aldığında, elemanı yeniden bulabilirsin. Bu, elemanın güncellenmiş bir referansa sahip olmasını sağlar.

Python:
element = driver.find_element_by_id('element_id')

eğer bu verdiklerim işine yaramaz ise,

elemana erişmek için kullanılan CSS selector veya XPath hala geçerliyse, bunları kullanabilirsin. Bazı durumlarda, farklı bir seçici kullanmak hata almanı önleyebilir.
Çok teşekkür ederim, çok güzel açıklamışsınız. Yeni görüyorum mesajınızı, kusura bakmayın dün müsait değildim. Ben bu söylediklerinizin hepsini denedim ama şöyle bir eklemede bulunayım. Yanlış satırda veya döngünün yanlış yerinde eklemiş olabilirim bu dediklerinizi. Ben pcye geçince sizinle kodları paylaşsam siz bir bakınabilir misiniz? Zaten gayet kolay ve kısa kodlar. @ugurtaylanc

try:
driver = webdriver.Chrome()
driver.get("MANN-FILTER Katalog Avrupa (Online) - Araçlar Kamyon + Otobüs")

path = "codes.xlsx"
wb = openpyxl.load_workbook(path)
sheet = wb.active
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "onetrust-accept-btn-handler")))
cerezClick = driver.find_element(By.ID, "onetrust-accept-btn-handler")
cerezClick.click()


WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "dropdownsHerstellerSelectInput")))
ureticiListe = driver.find_elements(By.CSS_SELECTOR, "#dropdownsHerstellerSelectItems > .rf-sel-opt")
for uretici in ureticiListe:
ureticiInput = driver.find_element(By.ID, "dropdownsHerstellerSelectInput")
ureticiInput.clear()
ureticiInput.send_keys(uretici.get_attribute("textContent"))
driver.switch_to.active_element.send_keys(Keys.ENTER)

WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "dropdownsModellreihe_SelectInput")))
modelListe = driver.find_elements(By.CSS_SELECTOR, "#dropdownsModellreihe_SelectItems > .rf-sel-opt")

for model in modelListe:
try:
WebDriverWait(driver, 5).until(EC.visibility_of_element_located((By.ID, "dropdownsModellreihe_SelectInput")))
modelInput = driver.find_element(By.ID, "dropdownsModellreihe_SelectInput")
modelInput.clear()
modelInput.send_keys(model.get_attribute("textContent"))
driver.switch_to.active_element.send_keys(Keys.ENTER)
except StaleElementReferenceException:
WebDriverWait(driver, 5).until(EC.visibility_of_element_located((By.ID, "dropdownsModellreihe_SelectInput")))
modelInput = driver.find_element(By.ID, "dropdownsModellreihe_SelectInput")
modelInput.clear()
modelInput.send_keys(model.get_attribute("textContent"))
driver.switch_to.active_element.send_keys(Keys.ENTER)

WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".table.vehicleTable > .row")))
tabloSatirlar = driver.find_elements(By.CSS_SELECTOR, ".table.vehicleTable > .row")

for satir in tabloSatirlar:
link = satir.find_element(By.CSS_SELECTOR, "a")
link.click()

satirLinkler = driver.find_elements(By.CSS_SELECTOR, ".partsTable > .partRow > .column > .tableContent > .part_title > .partsText")

for link in satirLinkler:
print("linkText:", link.text)
"""
time.sleep(3)
wb.save(path)
print("Excel'e aktarıldı")
"""

except KeyboardInterrupt:
print("Kullanıcı tarafından kesildi. Uygulama kapatılıyor.")
#wb.save(path)


@ugurtaylanc kod bu hocam.
 
Son düzenleme:
Merhaba,
Kodunuzu incelediğimde, "StaleElementReferenceException" hatasının nedenini sanırım buldum.

İncelediğim kadarıyla, "StaleElementReferenceException" hatası, model seçimi döngüsünde oluşuyor gibi görünüyor. Özellikle, WebDriverWait kullanıldığı sırada bu hatanın ortaya çıkması muhtemeldir. Bu hatayı çözmek için, model seçimi döngüsünde WebDriverWait kullanımını biraz değiştirmen gerekebilir.

Aşağıda sizin kodunuzu kullanarak bir örnek kod oluşturdum kontrol edebilir misiniz ?

Python:
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import Chrome
from selenium.common.exceptions import StaleElementReferenceException
import openpyxl

try:
    driver = Chrome()
    driver.get("MANN-FILTER Katalog Avrupa (Online) - Araçlar Kamyon + Otobüs")

    path = "codes.xlsx"
    wb = openpyxl.load_workbook(path)
    sheet = wb.active

    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "onetrust-accept-btn-handler")))
    cerezClick = driver.find_element(By.ID, "onetrust-accept-btn-handler")
    cerezClick.click()

    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "dropdownsHerstellerSelectInput")))
    ureticiListe = driver.find_elements(By.CSS_SELECTOR, "#dropdownsHerstellerSelectItems > .rf-sel-opt")
    for uretici in ureticiListe:
        ureticiInput = driver.find_element(By.ID, "dropdownsHerstellerSelectInput")
        ureticiInput.clear()
        ureticiInput.send_keys(uretici.get_attribute("textContent"))
        driver.switch_to.active_element.send_keys(Keys.ENTER)

        # Model seçimi için WebDriverWait kullanımını buraya taşıyoruz
        WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "dropdownsModellreihe_SelectInput")))

        modelInput = driver.find_element(By.ID, "dropdownsModellreihe_SelectInput")
        modelInput.clear()
        modelInput.send_keys(uretici.get_attribute("textContent"))
        driver.switch_to.active_element.send_keys(Keys.ENTER)

        WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".table.vehicleTable > .row")))
        tabloSatirlar = driver.find_elements(By.CSS_SELECTOR, ".table.vehicleTable > .row")

        for satir in tabloSatirlar:
            link = satir.find_element(By.CSS_SELECTOR, "a")
            link.click()

        satirLinkler = driver.find_elements(By.CSS_SELECTOR, ".partsTable > .partRow > .column > .tableContent > .part_title > .partsText")

        for link in satirLinkler:
            print("linkText:", link.text)

except KeyboardInterrupt:
    print("Kullanıcı tarafından kesildi. Uygulama kapatılıyor.")

Umarım bu değişiklik sorununu çözmeye yardımcı olur..
 
Merhaba,
Kodunuzu incelediğimde, "StaleElementReferenceException" hatasının nedenini sanırım buldum.

İncelediğim kadarıyla, "StaleElementReferenceException" hatası, model seçimi döngüsünde oluşuyor gibi görünüyor. Özellikle, WebDriverWait kullanıldığı sırada bu hatanın ortaya çıkması muhtemeldir. Bu hatayı çözmek için, model seçimi döngüsünde WebDriverWait kullanımını biraz değiştirmen gerekebilir.

Aşağıda sizin kodunuzu kullanarak bir örnek kod oluşturdum kontrol edebilir misiniz ?

Python:
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import Chrome
from selenium.common.exceptions import StaleElementReferenceException
import openpyxl

try:
    driver = Chrome()
    driver.get("MANN-FILTER Katalog Avrupa (Online) - Araçlar Kamyon + Otobüs")

    path = "codes.xlsx"
    wb = openpyxl.load_workbook(path)
    sheet = wb.active

    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "onetrust-accept-btn-handler")))
    cerezClick = driver.find_element(By.ID, "onetrust-accept-btn-handler")
    cerezClick.click()

    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "dropdownsHerstellerSelectInput")))
    ureticiListe = driver.find_elements(By.CSS_SELECTOR, "#dropdownsHerstellerSelectItems > .rf-sel-opt")
    for uretici in ureticiListe:
        ureticiInput = driver.find_element(By.ID, "dropdownsHerstellerSelectInput")
        ureticiInput.clear()
        ureticiInput.send_keys(uretici.get_attribute("textContent"))
        driver.switch_to.active_element.send_keys(Keys.ENTER)

        # Model seçimi için WebDriverWait kullanımını buraya taşıyoruz
        WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "dropdownsModellreihe_SelectInput")))

        modelInput = driver.find_element(By.ID, "dropdownsModellreihe_SelectInput")
        modelInput.clear()
        modelInput.send_keys(uretici.get_attribute("textContent"))
        driver.switch_to.active_element.send_keys(Keys.ENTER)

        WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".table.vehicleTable > .row")))
        tabloSatirlar = driver.find_elements(By.CSS_SELECTOR, ".table.vehicleTable > .row")

        for satir in tabloSatirlar:
            link = satir.find_element(By.CSS_SELECTOR, "a")
            link.click()

        satirLinkler = driver.find_elements(By.CSS_SELECTOR, ".partsTable > .partRow > .column > .tableContent > .part_title > .partsText")

        for link in satirLinkler:
            print("linkText:", link.text)

except KeyboardInterrupt:
    print("Kullanıcı tarafından kesildi. Uygulama kapatılıyor.")

Umarım bu değişiklik sorununu çözmeye yardımcı olur..


File "c:\Users\isra0\OneDrive\Masaüstü\green-site\onerilen.py", line 34, in <module>
modelInput.send_keys(uretici.get_attribute("textContent"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\isra0\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\webelement.py", line 177, in get_attribute
attribute_value = self.parent.execute_script(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\isra0\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 404, in execute_script
return self.execute(command, {"script": script, "args": converted_args})["value"]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\isra0\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 344, in execute
self.error_handler.check_response(response)
File "C:\Users\isra0\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 229, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found

bu hatayı aldım verdiğiniz kodda. Model döngüsünü kaldırmışsınız sanırım ama etki etmedi... :S @ugurtaylanc
 

Geri
Yukarı