Takip et

Selenium’da findElement ve findElements Metotları: Kapsamlı Bir Rehber ve Örnekler

Selenium’da findElement ve findElements Metotları: Kapsamlı Bir Rehber ve Örnekler Web otomasyon testlerinde ve veri kazıma (web scraping) işlem

Selenium’da findElement ve findElements Metotları: Kapsamlı Bir Rehber ve Örnekler

Web otomasyon testlerinde ve veri kazıma (web scraping) işlemlerinde Selenium WebDriver, web sayfalarıyla etkileşim kurmak için vazgeçilmez bir araçtır. Selenium’ın gücünün temelinde, web sayfasındaki belirli elementleri bulma ve onlarla etkileşim kurma yeteneği yatar. Bu yetenek, özellikle findElement() ve findElements() metotları aracılığıyla sağlanır. Bu makale, bu iki kritik metodu, aralarındaki farkları, nasıl kullanılacaklarını ve en iyi uygulama yöntemlerini detaylı örneklerle ele alacaktır.

Selenium WebDriver ve Web Elementleri

Selenium WebDriver, tarayıcılarla doğrudan etkileşim kurarak web uygulamalarını otomatikleştiren bir API setidir. Bir web sayfası, metin kutuları, düğmeler, bağlantılar, resimler, tablolar ve daha fazlası gibi çeşitli web elementlerinden oluşur. Selenium ile bu elementleri bulmak, tıklamak, metin girmek, özelliklerini okumak gibi işlemler gerçekleştirebiliriz. Elementleri bulmak için kullanılan anahtar kavram ise “locator”lardır (konumlandırıcılar).

Locator’lar (Konumlandırıcılar): Web Elementlerini Bulmanın Anahtarı

Bir web sayfasındaki elementleri benzersiz bir şekilde tanımlamak için çeşitli stratejiler kullanılır. Bu stratejilere locator denir. Selenium, elementleri bulmak için aşağıdaki yaygın locator türlerini destekler:

id

Bir elementin HTML içinde benzersiz bir id niteliği varsa, bu en güvenilir ve hızlı locator’dır. HTML standartlarına göre id değerleri sayfa içinde benzersiz olmalıdır.


// Örnek HTML: 
WebElement usernameField = driver.findElement(By.id("username"));

name

Elementin name niteliğini kullanarak bulur. Genellikle form elementleri için kullanılır.


// Örnek HTML: 
WebElement passwordField = driver.findElement(By.name("sifre"));

className

Elementin class niteliğini kullanarak bulur. Birden fazla element aynı sınıfa sahip olabilir, bu yüzden findElement() kullanıldığında ilk eşleşen element döndürülür.


// Örnek HTML: 

tagName

Elementin HTML etiket adını kullanarak bulur (örn. ,

, ). Genellikle findElements() ile belirli bir türdeki tüm elementleri toplamak için kullanılır.


// Örnek HTML: Link
WebElement firstLink = driver.findElement(By.tagName("a"));

linkText

Sadece (bağlantı) elementleri için kullanılır. Bağlantının tam görünen metnini eşleştirir.


// Örnek HTML: Hakkımızda
WebElement aboutLink = driver.findElement(By.linkText("Hakkımızda"));

partialLinkText

Yine sadece elementleri için kullanılır, ancak bağlantının görünen metninin bir kısmını eşleştirir.


// Örnek HTML: Bize Ulaşın
WebElement contactLink = driver.findElement(By.partialLinkText("Ulaşın"));

cssSelector

CSS seçicilerini kullanarak elementleri bulur. Oldukça güçlü ve esnektir, genellikle XPath’ten daha hızlıdır ve okunabilirliği daha iyidir.


// ID ile: #username
// Class ile: .btn-primary
// Tag ve class ile: input.input-field
// Nitelik ile: input[name='sifre']
WebElement usernameField = driver.findElement(By.cssSelector("#username"));
WebElement loginButton = driver.findElement(By.cssSelector(".btn-primary"));

xpath

XML Path Language (XPath) kullanarak elementleri bulur. En güçlü ve esnek locator’dır, ancak karmaşık XPath ifadeleri okunması ve bakımı zor olabilir. Hem mutlak (absolute) hem de göreceli (relative) yollarla kullanılabilir.


// Mutlak XPath (genellikle önerilmez): /html/body/div[1]/input[1]
// Göreceli XPath: //input[@id='username']
// Nitelik içeren: //button[text()='Giriş Yap']
WebElement usernameField = driver.findElement(By.xpath("//input[@id='username']"));
WebElement loginButton = driver.findElement(By.xpath("//button[text()='Giriş Yap']"));

Doğru locator’ı seçmek, testlerinizin sağlamlığı ve performansı için kritik öneme sahiptir. Genellikle id, ardından name, cssSelector ve son olarak xpath tercih edilir.

findElement() Metodu: Tek Bir Elementi Bulma

findElement() metodu, web sayfasında belirtilen locator stratejisine uyan ilk web elementini bulmak ve döndürmek için kullanılır. Eğer hiçbir element bulunamazsa, bu metod bir NoSuchElementException fırlatır.

Kullanım Amacı

  • Belirli bir düğmeye tıklamak.
  • Bir metin kutusuna veri girmek.
  • Bir elementin metnini veya niteliğini okumak.
  • Bir elementin varlığını doğrulamak (hata yakalama ile birlikte).

Sözdizimi (Syntax)


WebElement element = driver.findElement(By.locatorStrategy("locatorValue"));

Dönüş Tipi

findElement() metodu, bulunan web elementini temsil eden bir WebElement nesnesi döndürür.

Örnek Senaryo ve Kod

Hayali bir HTML sayfamız olduğunu varsayalım:





    Test Sayfası


    

Selenium Test Başlığı

Bu bir giriş paragrafıdır.

Hakkımızda İletişim Ürünler

Ürün 1

Açıklama 1

Ürün 2

Açıklama 2

Bu sayfadaki elementleri findElement() kullanarak bulalım:


import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.NoSuchElementException; // Hata yakalama için

public class FindElementExamples {

    public static void main(String[] args) {
        // WebDriver'ı başlatma (Chrome için)
        // System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver"); // Kendi chromedriver yolunuzu belirtin
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();

        // Test edilecek HTML dosyasını açma (yerel dosya veya bir URL olabilir)
        // Gerçek bir senaryoda bir URL açarsınız: driver.get("https://www.example.com");
        driver.get("file:///C:/Users/YourUser/Desktop/test_page.html"); // Kendi dosya yolunuzu belirtin

        try {
            // 1. By.id ile element bulma
            WebElement mainHeader = driver.findElement(By.id("mainHeader"));
            System.out.println("Ana Başlık Metni (ID): " + mainHeader.getText());

            // 2. By.name ile element bulma
            WebElement usernameField = driver.findElement(By.name("kullaniciAdi"));
            usernameField.sendKeys("testKullanici");
            System.out.println("Kullanıcı Adı alanına metin girildi.");

            // 3. By.className ile element bulma
            WebElement loginButton = driver.findElement(By.className("btn-primary"));
            System.out.println("Giriş Düğmesi Metni (Class Name): " + loginButton.getText());
            // loginButton.click(); // Düğmeye tıklama işlemi

            // 4. By.tagName ile element bulma (ilk h1 elementi)
            WebElement firstH1 = driver.findElement(By.tagName("h1"));
            System.out.println("İlk H1 Etiketi Metni (Tag Name): " + firstH1.getText());

            // 5. By.linkText ile element bulma
            WebElement aboutLink = driver.findElement(By.linkText("Hakkımızda"));
            System.out.println("Hakkımızda Bağlantısı Metni (Link Text): " + aboutLink.getText());

            // 6. By.partialLinkText ile element bulma
            WebElement contactLink = driver.findElement(By.partialLinkText("İletişim"));
            System.out.println("İletişim Bağlantısı Metni (Partial Link Text): " + contactLink.getText());

            // 7. By.cssSelector ile element bulma
            WebElement passwordField = driver.findElement(By.cssSelector("input[name='sifre']"));
            passwordField.sendKeys("gizliSifre");
            System.out.println("Şifre alanına metin girildi (CSS Selector).");

            WebElement introParagraph = driver.findElement(By.cssSelector("p.intro-paragraph"));
            System.out.println("Giriş Paragrafı Metni (CSS Selector): " + introParagraph.getText());

            // 8. By.xpath ile element bulma
            WebElement product1Header = driver.findElement(By.xpath("//div[@class='product-item']/h3[text()='Ürün 1']"));
            System.out.println("Ürün 1 Başlığı Metni (XPath): " + product1Header.getText());

            // Var olmayan bir elementi bulmaya çalışma (NoSuchElementException fırlatır)
            try {
                WebElement nonExistentElement = driver.findElement(By.id("nonExistent"));
                System.out.println("Bulunan element: " + nonExistentElement.getText());
            } catch (NoSuchElementException e) {
                System.out.println("Hata: 'nonExistent' ID'sine sahip element bulunamadı. (Beklenen hata)");
            }

        } catch (NoSuchElementException e) {
            System.err.println("Bir element bulunamadı: " + e.getMessage());
        } finally {
            // Tarayıcıyı kapatma
            driver.quit();
        }
    }
}

findElements() Metodu: Birden Fazla Elementi Bulma

findElements() metodu, web sayfasında belirtilen locator stratejisine uyan tüm web elementlerini bulmak ve bir liste olarak döndürmek için kullanılır. Eğer hiçbir element bulunamazsa, bu metod bir NoSuchElementException fırlatmaz; bunun yerine boş bir List döndürür. Bu, findElement() ile arasındaki en önemli farklardan biridir.

Kullanım Amacı

  • Bir sayfadaki tüm bağlantıları toplamak.
  • Bir tablodaki tüm satırları veya hücreleri almak.
  • Belirli bir sınıfa sahip tüm elementleri işlemek.
  • Dinamik olarak oluşturulan element gruplarını yönetmek.

Sözdizimi (Syntax)


List elements = driver.findElements(By.locatorStrategy("locatorValue"));

Dönüş Tipi

findElements() metodu, WebElement nesnelerinden oluşan bir List döndürür.

Örnek Senaryo ve Kod

Yukarıdaki aynı hayali HTML sayfasını kullanarak findElements() ile birden fazla elementi bulalım:


import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;

public class FindElementsExamples {

    public static void main(String[] args) {
        // WebDriver'ı başlatma (Chrome için)
        // System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver"); // Kendi chromedriver yolunuzu belirtin
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();

        // Test edilecek HTML dosyasını açma
        driver.get("file:///C:/Users/YourUser/Desktop/test_page.html"); // Kendi dosya yolunuzu belirtin

        try {
            // 1. By.tagName ile tüm bağlantıları bulma
            List allLinks = driver.findElements(By.tagName("a"));
            System.out.println("\n--- Tüm Bağlantılar (Tag Name: a) ---");
            if (allLinks.isEmpty()) {
                System.out.println("Sayfada hiç bağlantı bulunamadı.");
            } else {
                System.out.println("Bulunan bağlantı sayısı: " + allLinks.size());
                for (WebElement link : allLinks) {
                    System.out.println("  Metin: " + link.getText() + ", URL: " + link.getAttribute("href"));
                }
            }

            // 2. By.className ile belirli bir sınıfa sahip tüm elementleri bulma
            List navLinks = driver.findElements(By.className("nav-link"));
            System.out.println("\n--- Navigasyon Bağlantıları (Class Name: nav-link) ---");
            if (navLinks.isEmpty()) {
                System.out.println("Sayfada 'nav-link' sınıfına sahip element bulunamadı.");
            } else {
                System.out.println("Bulunan navigasyon bağlantısı sayısı: " + navLinks.size());
                for (WebElement link : navLinks) {
                    System.out.println("  Metin: " + link.getText());
                }
            }

            // 3. By.cssSelector ile tüm ürün öğelerini bulma
            List productItems = driver.findElements(By.cssSelector(".product-item"));
            System.out.println("\n--- Ürün Öğeleri (CSS Selector: .product-item) ---");
            if (productItems.isEmpty()) {
                System.out.println("Sayfada hiç ürün öğesi bulunamadı.");
            } else {
                System.out.println("Bulunan ürün öğesi sayısı: " + productItems.size());
                for (int i = 0; i < productItems.size(); i++) {
                    WebElement item = productItems.get(i);
                    // Ürün başlığını ve açıklamasını bulma (element içinden findElement)
                    WebElement title = item.findElement(By.tagName("h3"));
                    WebElement description = item.findElement(By.tagName("p"));
                    System.out.println("  Ürün " + (i + 1) + ": Başlık: " + title.getText() + ", Açıklama: " + description.getText());
                }
            }

            // 4. By.xpath ile tüm H3 başlıklarını bulma
            List allH3s = driver.findElements(By.xpath("//h3"));
            System.out.println("\n--- Tüm H3 Başlıkları (XPath: //h3) ---");
            if (allH3s.isEmpty()) {
                System.out.println("Sayfada hiç H3 başlığı bulunamadı.");
            } else {
                System.out.println("Bulunan H3 başlığı sayısı: " + allH3s.size());
                for (WebElement h3 : allH3s) {
                    System.out.println("  Başlık: " + h3.getText());
                }
            }

            // Var olmayan bir locator ile arama (boş liste döndürür)
            List nonExistentElements = driver.findElements(By.id("nonExistentClass"));
            System.out.println("\n--- Var Olmayan Elementler (ID: nonExistentClass) ---");
            if (nonExistentElements.isEmpty()) {
                System.out.println("'nonExistentClass' ID'sine sahip element bulunamadı. (Boş liste döndü)");
            } else {
                System.out.println("Hata: Var olmayan elementler bulundu!");
            }

        } finally {
            // Tarayıcıyı kapatma
            driver.quit();
        }
    }
}

findElement() ve findElements() Arasındaki Temel Farklar

Bu iki metod arasındaki farkları anlamak, test senaryolarınızı doğru bir şekilde tasarlamanız için hayati öneme sahiptir:

Özellik findElement() findElements()
Amaç Tek bir web elementi bulmak. Belirli bir kritere uyan tüm web elementlerini bulmak.
Dönüş Tipi WebElement List
Element Bulunamazsa NoSuchElementException fırlatır. Boş bir List döndürür. Hata fırlatmaz.
Kullanım Senaryosu Tekil bir form alanı, düğme, başlık vb. ile etkileşim kurmak. Bir sayfadaki tüm bağlantıları, tablo satırlarını, ürün kartlarını vb. toplamak ve işlemek.
Performans Genellikle daha hızlıdır çünkü ilk eşleşmeyi bulduğunda durur. Tüm eşleşmeleri bulmak için sayfanın tamamını tarayabilir, bu nedenle daha yavaş olabilir.

En İyi Uygulamalar ve İpuçları

Selenium ile elementleri bulurken verimliliği, sağlamlığı ve bakım kolaylığını artırmak için bazı en iyi uygulamalar mevcuttur:

1. Sağlam Locator’lar Seçin

  • id‘yi Tercih Edin: Mümkünse her zaman id kullanın. En hızlı ve en güvenilir locator’dır çünkü benzersiz olması beklenir.
  • name ve className: Eğer id yoksa, name veya benzersiz bir className deneyin.
  • cssSelector Kullanın: cssSelector, xpath‘e göre genellikle daha hızlı, daha okunaklı ve daha az kırılgandır. Özellikle karmaşık elementleri bulmak için güçlü bir alternatiftir.
  • xpath‘i Dikkatli Kullanın: Sadece cssSelector‘ın yetersiz kaldığı durumlarda (örn. üst elemente göre arama, metin içeriğine göre arama) xpath kullanın. Göreceli XPath kullanmaya özen gösterin (//div[@id='myDiv'] yerine /html/body/div[1]/div[2] gibi mutlak XPath’lerden kaçının).
  • Dinamik Değerlerden Kaçının: Otomatik olarak oluşturulan veya her yüklemede değişen id‘ler veya class‘lardan kaçının.

2. Beklemeler (Waits) Kullanın

Modern web uygulamaları dinamiktir. Elementler sayfa yüklendikten sonra AJAX çağrıları veya JavaScript etkileşimleri ile görünebilir, kaybolabilir veya değişebilir. Elementleri bulmaya çalışmadan önce uygun beklemeleri kullanmak, NoSuchElementException hatalarını önler ve testlerinizin daha sağlam olmasını sağlar.

  • Implicit Wait (Örtülü Bekleme): WebDriver’a, bir elementi bulmaya çalışırken belirli bir süre boyunca beklemesini söyler. Bir kez ayarlandığında, tüm findElement() ve findElements() çağrıları için geçerlidir.
  • 
        driver.manage().timeouts().implicitlyWait(java.time.Duration.ofSeconds(10));
        
  • Explicit Wait (Açık Bekleme): Belirli bir koşulun gerçekleşmesini beklemek için kullanılır. Daha esnektir ve belirli bir elementin görünür, tıklanabilir veya mevcut olmasını beklemek gibi senaryolarda çok etkilidir.
  • 
        import org.openqa.selenium.support.ui.WebDriverWait;
        import org.openqa.selenium.support.ui.ExpectedConditions;
        import java.time.Duration;
    
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myElement")));
        

3. Hata Yönetimi

  • findElement() için try-catch: Eğer bir elementin varlığı opsiyonelse veya bulunamayabileceği bir senaryo varsa, NoSuchElementException‘ı yakalamak için try-catch blokları kullanın.
  • findElements() için isEmpty() Kontrolü: findElements() boş bir liste döndürdüğünde hata fırlatmadığı için, liste üzerinde işlem yapmadan önce list.isEmpty() metodunu kullanarak listenin boş olup olmadığını kontrol edin.

4. Element Zincirleme (Chaining)

Bazen bir elementin altındaki bir elementi bulmanız gerekebilir. Bu durumda, önce ana elementi bulup, ardından bu element üzerinden findElement() veya findElements() çağırabilirsiniz. Bu, locator’larınızı daha kısa ve okunabilir hale getirebilir.


// product-list div'i içindeki tüm product-item'ları bulma
WebElement productListDiv = driver.findElement(By.className("product-list"));
List productItems = productListDiv.findElements(By.className("product-item"));

for (WebElement item : productItems) {
    WebElement productTitle = item.findElement(By.tagName("h3"));
    System.out.println("Ürün Başlığı: " + productTitle.getText());
}

5. Page Object Model (POM) Kullanımı

Büyük projelerde, locator’ları ve elementlerle etkileşim metotlarını ayrı sınıf dosyalarında (Page Objects) tanımlamak, kodunuzun daha düzenli, okunabilir ve bakımı kolay olmasını sağlar. Bu yaklaşım, element locator’larının tek bir yerde tanımlanmasını ve gerektiğinde kolayca güncellenmesini sağlar.

Gelişmiş Konulara Kısa Bir Bakış

findElement ve findElements metotları temel olsa da, web otomasyonunda karşılaşabileceğiniz bazı daha karmaşık senaryolar vardır:

  • Iframes (Çerçeveler): Bir web sayfası içinde başka bir web sayfası barındıran