XPath Rehberi

Bu eğitimde, ‘HTML <https:/’nin isteğe bağlı bölümlerini seçmek için kullanılabilecek bir sorgulama dili olan ‘XPath <https://en.wikipedia.org/wiki/XPath>’_ hakkında hafif bir giriş yapılacaktır. /en.wikipedia.org/wiki/HTML>`_ calibre’deki belgeler. XPath yaygın olarak kullanılan bir standarttır ve Google’da araştırıldığında tonlarca bilgi elde edilir. Ancak bu eğitim, yapılandırılmamış bir HTML belgesinde bölüm başlıklarını bulmak gibi e-kitapla ilgili görevler için XPath kullanımına odaklanmaktadır.

Etiket ismine göre seçim

Seçimin en basit formu etiketleri isme göre seçmektir. Örneğin; belgedeki tüm <h2> etiketlerini seçmek istediğinizi düşünelim. XPath sorgusu basitçe şöyle olacaktır:

//h:h2        (Selects all <h2> tags)

Baştaki // öneki belgedeki tüm düzeylerde ara anlamına gelmektedir. Şimdi ise <a> etiketi içindeki ``<span>``etiketlerini arıyor olalım. Bunu yapan sorgu:

//h:a/h:span    (Selects <span> tags inside <a> tags)

Eğer belgedeki belirli bir düzeydeki etiketleri arayacak olursanız öneki değiştirin:

/h:body/h:div/h:p (Selects <p> tags that are children of <div> tags that are
             children of the <body> tag)

Bu yalnızca Örnek e-kitap içindeki <p>XPath kullanımını göstermek için çok kısa bir e-kitap.</p> ile eşleşir ancak diğer <p> etiketlerinden hiçbiriyle eşleşmez. Yukarıdaki örneklerde h: öneki XHTML etiketleriyle eşleşmesi için gereklidir. Bunun nedeni dahili olarak calibre’nin tüm içeriği XHTML olarak temsil etmesidir. XHTML’de etiketlerin bir ad alanı vardır ve h: HTML etiketleri için ad alanı önekidir.

Şimdi <h1> ve <h2> etiketlerini seçmek isteyelim. Bunu yapabilmek için XPath’in predicate isimli yapısına ihtiyacımız vardır. Bir predicate basitçe etiketleri seçmek için bir testtir. Testler keyfi güçlü olabilir ve bu rehber ilerledikçe, daha güçlü örneklerini göreceksiniz. Bir predicate, test ifadesinin kare parantezler içine alınmasıyla oluşturulur:

//*[name()='h1' or name()='h2']

Bu XPath ifadesinde pek çok yenilik bulunmaktadır. Bunların ilki * karakteridir. herhangi bir etiketle eşleş anlamına gelmektedir. Şimdi test ifadesine bakalım name()='h1' or name()='h2'. name() tümleşik fonksiyona bir örnektir. Basitçe etiketin adını değerlendirir. Bu nedenle onu kullanarak, isimleri h1 veya h2 olan etiketleri seçebiliriz. name() fonksiyonunun isim alanlarını yok saydığını ve bu nedenle h: ön ekine ihtiyaç olmadığına dikkat edin. XPath çok fazla tümleşik fonksiyona sahiptir. Bunlardan bir kaçına bu rehberde değinilecektir.

Özniteliğe göre seçmek

Etiketleri özniteliklerine göre seçmek için bu ifadelerin kullanılması gereklidir:

//*[@style]              (Select all tags that have a style attribute)
//*[@class="chapter"]    (Select all tags that have class="chapter")
//h:h1[@class="bookTitle"] (Select all h1 tags that have class="bookTitle")

Buradaki @ operatörü etiketin özniteliğine karşılık gelir. Öznitelik değerleriyle ilgili daha karmaşık eşleşmeler için XPath tümleşik fonksiyonlarını kullanabilirsiniz.

Etiket içeriğine göre seçmek

XPath kullanarak etiketleri içerdikleri metinlere göre seçebilirsiniz. Bunu yapmanın en iyi yolu re:test() tümleşik fonksiyonunun düzenli ifadelerini kullanmaktır:

//h:h2[re:test(., 'chapter|section', 'i')] (Selects <h2> tags that contain the words chapter or
                                          section)

Buradaki . operatörü etiketin içeriğine karşılık gelir, @ operatörünün özniteliklere karşılık gelmesi gibidir.

Örnek e-kitap

<html>
    <head>
        <title>A very short e-book</title>
        <meta name="charset" value="utf-8" />
    </head>
    <body>
        <h1 class="bookTitle">A very short e-book</h1>
        <p style="text-align:right">Written by Kovid Goyal</p>
        <div class="introduction">
            <p>A very short e-book to demonstrate the use of XPath.</p>
        </div>

        <h2 class="chapter">Chapter One</h2>
        <p>This is a truly fascinating chapter.</p>

        <h2 class="chapter">Chapter Two</h2>
        <p>A worthy continuation of a fine tradition.</p>
    </body>
</html>

XPath tümleşik fonksiyonları

name()

Mevcut etiketin adı.

contains()

contains(s1, s2) ifadesi eğer s1, s2’yi içerirse true döndürür.

re:test()

re:test(src, model, flags), src dizesi pattern normal ifadesiyle eşleşiyorsa `true’ değerini döndürür. Özellikle kullanışlı bir bayrak ``i``dir, eşleştirmeyi büyük/küçük harfe duyarsız hale getirir. Düzenli ifadelerin sözdizimi hakkında iyi bir başlangıç ​​noktası, ‘regexp sözdizimi <https://docs.python.org/library/re.html>’_ adresinde bulunabilir.