Çözüldü Python Selenium 4.3.0 ile "presence_of_element_located" hatası

Bu konu çözüldü olarak işaretlenmiştir. Çözülmediğini düşünüyorsanız konuyu rapor edebilirsiniz.
Katılım
8 Eylül 2018
Mesajlar
9.647
Makaleler
8
Çözümler
224
Yer
İstanbul
Merhaba arkadaşlar,

Selenium 4.3.0 ve sonrasında, presence_of_element_located işlevi ile ilgili bir hata alıyorum. Daha önce presence_of işlevini kullanıyordum, ancak Selenium 4.3.0'da bu işlev kaldırıldı. presence_of_element_located işlevini kullanmak istiyorum fakat şu hatayı alıyorum:

module 'selenium.webdriver.support.expected_conditions' has no attribute 'presence_of

Yapmaya çalıştığım şey, WebDriverWait ile belirli bir öğenin sayfada yüklenmesini beklemek. Ancak, presence_of_element_located işlevini doğru kullanmama rağmen hata alıyorum.

Selenium 4.3.0 ve sonrasındaki güncellemeler ile bu işlevin doğru kullanımına dair öneriler veya çözüm önerileri alabilir miyim?

Kod Örneği:​


Python:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
# Kullanım şekli:
WebDriverWait(browser, 15).until(
EC.presence_of_element_located((By.XPATH, '//*[@id="__layout"]/div/div/section[3]/div[3]/div[1]/div[1]/div[1]/div[2]'))

Veri kazımada kullandığım kod:

Python:
import pandas as pd
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup as bs
import time
import random
import logging

# Logging ayarları (hata takibi için)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Chrome ayarları
options = Options()
options.add_argument("--start-maximized")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)

# Farklı user-agent'lar
user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"
]

# WebDriver yolu (kendi yolunu güncelle)
driver_path = r"C:\Users\Emre\Desktop\chromedriver-win64\chromedriver.exe"
service = Service(driver_path)
browser = webdriver.Chrome(service=service, options=options)

# İlan linkleri ve detaylar için listeler
base_url = "https://www.hepsiemlak.com/atakum-satilik"
linkdata = []
adinfos = []

# Sayfalama ile ilan linklerini toplama
def collect_links():
    page = 1
    max_pages = 1
    while len(linkdata) < 1 and page <= max_pages:
        url = f"{base_url}?page={page}"
        try:
            # Rastgele user-agent seçimi
            options.add_argument(f"--user-agent={random.choice(user_agents)}")
            browser.get(url)
            time.sleep(random.uniform(3, 6))  # Daha doğal bekleme süresi
         
            # Sayfayı biraz kaydırarak insan davranışı simüle et
            browser.execute_script("window.scrollTo(0, document.body.scrollHeight / 2);")
            time.sleep(random.uniform(1, 3))
         
            soup = bs(browser.page_source, "lxml")
            links = soup.find_all("a", {"class": "card-link"})
         
            if not links:
                logging.info("Daha fazla ilan bulunamadı.")
                break
         
            for link in links:
                href = link.get("href")
                if href and href not in linkdata:
                    full_url = "https://www.hepsiemlak.com" + href
                    linkdata.append(full_url)
         
            logging.info(f"Sayfa {page} tarandı. Toplam {len(linkdata)} ilan linki toplandı.")
            page += 1
            time.sleep(random.uniform(5, 10))  # Daha uzun ve rastgele bekleme
     
        except Exception as e:
            logging.error(f"Link toplama hatası (Sayfa {page}): {e}")
            time.sleep(random.uniform(10, 15))  # Hata sonrası daha uzun bekleme
            continue

# İlan detaylarını çekme
def collect_details():
    counter = 1
    for url in linkdata:
        retries = 3
        while retries > 0:
            try:
                options.add_argument(f"--user-agent={random.choice(user_agents)}")
                browser.get(url)
             
                # WebDriverWait ile bekleme, presence_of ile elementin bulunmasını bekliyoruz
                WebDriverWait(browser, 15).until(
                    EC.presence_of((By.XPATH, '//*[@id="__layout"]/div/div/section[3]/div[3]/div[1]/div[1]/div[1]/div[2]'))
                )
                ilan_url = url

                logging.info(f"\n-----------------------------------\n{counter}")
                logging.info(f"Link: {ilan_url}")

                # Fiyat
                price = browser.find_element(By.XPATH, '//*[@id="__layout"]/div/div/section[3]/div[3]/div[1]/div[1]/div[1]/div[2]/div[1]').text.strip()
                logging.info(f"Fiyat: {price}")

                # Şehir, ilçe, mahalle
                try:
                    short_info = browser.find_elements(By.XPATH, '//*[@id="__layout"]/div/div/section[3]/div[3]/div[1]/div[1]/div[1]/div[2]/ul')
                    sehir = short_info[0].text.strip() if len(short_info) > 0 else "-"
                    ilce = short_info[1].text.strip() if len(short_info) > 1 else "-"
                    mahalle = short_info[2].text.strip() if len(short_info) > 2 else "-"
                except:
                    sehir = ilce = mahalle = "-"
                logging.info(f"Şehir: {sehir}")
                logging.info(f"İlçe: {ilce}")
                logging.info(f"Mahalle: {mahalle}")

                # Varsayılan değerler
                ilan_no = son_guncelleme = ilan_durumu = konut_tipi = oda_sayisi = banyo_sayisi = brut_net_m2 = kat_sayisi = bulundu_kat = bina_yasi = isinma_tipi = kredi_durumu = tapu_durumu = esya_durumu = kullanım_durumu = cephe = aidat = takas = "-"

                # Detaylı bilgiler
                details_container = browser.find_element(By.XPATH, "//*[@id='__layout']/div/div/section[3]/div[3]/div[1]/div[1]/div[1]/div[2]")
                detail_items = details_container.find_elements(By.XPATH, ".//li[contains(@class, 'spec-item')]")
             
                for item in detail_items:
                    detail = item.text.strip()
                    if "İlan no" in detail: ilan_no = detail.lstrip("İlan no ")
                    if "Son Güncelleme" in detail: son_guncelleme = detail.lstrip("Son Güncelleme ")
                    if "İlan Durumu" in detail: ilan_durumu = detail.lstrip("İlan Durumu ")
                    if "Konut Tipi" in detail: konut_tipi = detail.lstrip("Konut Tipi ")
                    if "Oda Sayısı" in detail: oda_sayisi = detail.lstrip("Oda Sayısı ")
                    if "Banyo Sayısı" in detail: banyo_sayisi = detail.lstrip("Banyo Sayısı ")
                    if "Brüt / Net M2" in detail:
                        brut_net_m2 = detail.lstrip("Brüt / Net M2 ").strip()
                        # Brüt ve Net M2'yi ayırma
                        brut_m2 = net_m2 = "-"
                        if brut_net_m2 != "-":
                            brut_net_parts = brut_net_m2.split("/")
                            if len(brut_net_parts) == 2:
                                brut_m2 = brut_net_parts[0]
                                net_m2 = brut_net_parts[1]
                    if "Kat Sayısı" in detail: kat_sayisi = detail.lstrip("Kat Sayısı ")
                    if "Bulunduğu Kat" in detail: bulundu_kat = detail.lstrip("Bulunduğu Kat ")
                    if "Bina Yaşı" in detail: bina_yasi = detail.lstrip("Bina Yaşı ")
                    if "Isınma Tipi" in detail: isinma_tipi = detail.lstrip("Isınma Tipi ")
                    if "Krediye Uygunluk" in detail: kredi_durumu = detail.split(" ")[2] if len(detail.split(" ")) > 2 else "-"
                    if "Tapu Durumu" in detail: tapu_durumu = detail.lstrip("Tapu Durumu ")
                    if "Eşya Durumu" in detail: esya_durumu = detail.split("Durumu ")[1] if "Durumu " in detail else "-"
                    if "Kullanım Durumu" in detail: kullanım_durumu = detail.lstrip("Kullanım Durumu ")
                    if "Cephe" in detail: cephe = detail.lstrip("Cephe ")
                    if "Aidat" in detail: aidat = detail.strip("Aidat ")
                    if "Takas" in detail: takas = detail.lstrip("Takas ")

                # Konsolda göster
                logging.info(f"İlan no: {ilan_no}")
                logging.info(f"Son Güncelleme: {son_guncelleme}")
                logging.info(f"İlan Durumu: {ilan_durumu}")
                logging.info(f"Konut Tipi: {konut_tipi}")
                logging.info(f"Oda Sayısı: {oda_sayisi}")
                logging.info(f"Banyo Sayısı: {banyo_sayisi}")
                logging.info(f"Brüt M2: {brut_m2}")
                logging.info(f"Net M2: {net_m2}")
                logging.info(f"Kat Sayısı: {kat_sayisi}")
                logging.info(f"Bulunduğu Kat: {bulundu_kat}")
                logging.info(f"Bina Yaşı: {bina_yasi}")
                logging.info(f"Isınma Tipi: {isinma_tipi}")
                logging.info(f"Krediye Uygunluk: {kredi_durumu}")
                logging.info(f"Tapu Durumu: {tapu_durumu}")
                logging.info(f"Eşya Durumu: {esya_durumu}")
                logging.info(f"Kullanım Durumu: {kullanım_durumu}")
                logging.info(f"Cephe: {cephe}")
                logging.info(f"Aidat: {aidat}")
                logging.info(f"Takas: {takas}")

                # Verileri dictionary olarak sakla
                advert_infos = {
                    "Link": ilan_url,
                    "Fiyat": price,
                    "Şehir": sehir,
                    "İlçe": ilce,
                    "Mahalle": mahalle,
                    "İlan no": ilan_no,
                    "Son Güncelleme": son_guncelleme,
                    "İlan Durumu": ilan_durumu,
                    "Konut Tipi": konut_tipi,
                    "Oda Sayısı": oda_sayisi,
                    "Banyo Sayısı": banyo_sayisi,
                    "Brüt M2": brut_m2,
                    "Net M2": net_m2,
                    "Kat Sayısı": kat_sayisi,
                    "Bulunduğu Kat": bulundu_kat,
                    "Bina Yaşı": bina_yasi,
                    "Isınma Tipi": isinma_tipi,
                    "Krediye Uygunluk": kredi_durumu,
                    "Tapu Durumu": tapu_durumu,
                    "Eşya Durumu": esya_durumu,
                    "Kullanım Durumu": kullanım_durumu,
                    "Cephe": cephe,
                    "Aidat": aidat,
                    "Takas": takas
                }
                adinfos.append(advert_infos)
                counter += 1
                time.sleep(random.uniform(5, 10))  # İlanlar arasında rastgele bekleme
                break  # Başarılıysa döngüden çık

            except Exception as e:
                logging.error(f"Hata alındı (İlan {counter}, Deneme {4-retries}): {e}")
                retries -= 1
                if retries > 0:
                    time.sleep(random.uniform(10, 20))  # Hata sonrası daha uzun bekleme
                else:
                    logging.error(f"İlan {counter} için tüm denemeler başarısız.")
                    break

    # Excel'e kaydet
    try:
        logging.info("\nVeri çekme işlemi tamamlandı...\nÇekilen veriler Excel dosyasına dönüştürülüyor...")
        df_data = pd.DataFrame(adinfos)
        df_data.to_excel("ilan_detaylari_final.xlsx", index=False)
        logging.info("\nVeriler Excel dosyasına dönüştürüldü...")
    except Exception as e:
        logging.error(f"Excel'e kaydetme hatası: {e}")

# Ana çalıştırma
def main():
    try:
        collect_links()
        collect_details()
    finally:
        browser.quit()
        logging.info("Program sonlandı.")

if __name__ == "__main__":
    main()

Sorun şu ki 2-3 hafta önceye kadar sorunsuz +1000 veri çekebilmiştim. 2-3 haftalık sürede ne güncellemesi geldi, takip de edemedim.

  • expected_conditions modülünü doğru import ettiğimden emin oldum.
  • Selenium sürümüm güncel ve Python sürümümle uyumlu.
  • presence_of_element_located fonksiyonunun yazımında bir hata bulunmuyor.
  • Selenium'u kaldırıp yeniden yükledim.
  • Doğru Python ortamında çalıştığımı kontrol ettim.
  • IDE ve editörümün önbelleğini temizledim.
  • Alternatif yöntemlerle (WebDriverWait içinde lambda) denemeler yaptım.
  • expected_conditions için doğru alias kullanımını (as EC) sağladım.
  • Olası hatalı selenium paketlerini temiz kurulumla değiştirdim.
  • Python ve Selenium paketlerinin uyumluluğunu ayrıca doğruladım.

@bitwise
 
Son düzenleme:
Çözüm
Calisma bilgisayarim yanimda degil, kodu test edemem su anda ama downgrade etmeyi deneyebilirsin madem eski versiyonda sorunsuz calisiyordu:

pip install selenium==4.29.0


pip eger ust versiyon yukluyse onu eskisiyle degistirecek.

4.29 cok da eski degil, eger spesifik versiyonla isin hallediliyorsa bence onunla takil, kafasina gore deprecate ettikleri her seyi duzeltmekle ugrassak proje gelistiremeyiz, o yuzden tavsiyem tum dependency'ler icin requirement.txt uzerinde versiyon belirleyip o sekilde ilerlemek. Gun gelince upgrade edersin.
  • presence_of diye bir şey yok.
  • presence_of_element_located var ve parametre olarak bir locator tuple (yani (By.XPATH, "path")) alır.
  • Hatan presence_of((By.XPATH, '...')) yazmış olmandan kaynaklı.
 
  • presence_of diye bir şey yok.
  • presence_of_element_located var ve parametre olarak bir locator tuple (yani (By.XPATH, "path")) alır.
  • Hatan presence_of((By.XPATH, '...')) yazmış olmandan kaynaklı.

expected_conditions yerine time.sleep() kullanınca sorun kısmen çözüldü. Dediğiniz şekilde deneyeceğim birazdan.
 
Calisma bilgisayarim yanimda degil, kodu test edemem su anda ama downgrade etmeyi deneyebilirsin madem eski versiyonda sorunsuz calisiyordu:

pip install selenium==4.29.0


pip eger ust versiyon yukluyse onu eskisiyle degistirecek.

4.29 cok da eski degil, eger spesifik versiyonla isin hallediliyorsa bence onunla takil, kafasina gore deprecate ettikleri her seyi duzeltmekle ugrassak proje gelistiremeyiz, o yuzden tavsiyem tum dependency'ler icin requirement.txt uzerinde versiyon belirleyip o sekilde ilerlemek. Gun gelince upgrade edersin.
 
Çözüm
Calisma bilgisayarim yanimda degil, kodu test edemem su anda ama downgrade etmeyi deneyebilirsin madem eski versiyonda sorunsuz calisiyordu:

pip install selenium==4.29.0


pip eger ust versiyon yukluyse onu eskisiyle degistirecek.

4.29 cok da eski degil, eger spesifik versiyonla isin hallediliyorsa bence onunla takil, kafasina gore deprecate ettikleri her seyi duzeltmekle ugrassak proje gelistiremeyiz, o yuzden tavsiyem tum dependency'ler icin requirement.txt uzerinde versiyon belirleyip o sekilde ilerlemek. Gun gelince upgrade edersin.

Hocam teşekkür ederim. Halihazırda Selenium 4.29 sürümündeydi, güncelleyerek yükselttim ve bu sorunu kısmen çözdüm.

Şimdi de çektiğim verileri alamıyorum. Sanırım Xpath kaynaklı, veri kazıma işine de yeni yeni girdiğim için burada acemiliğim tuttu. Veriyi çekebildiğimde dönüş sağlayacağım.

Şimdilik Xpath'leri deneye deneye ilerliyorum.

@bitwise çözdüm hocam. Sürüm 4.31'de yine hata aldım. Dediğiniz sürümü Terminal'den indirdim. Xpath'i güncelledim ve sorun çözüldü. Size çok teşekkür ediyorum.
 
Son düzenleme:

Technopat Haberler

Yeni konular

Geri
Yukarı