AngleSharp İle Web Kazıma Yapımı!

Grimner

Adanmış Üye
28 Mar 2020
6,308
4,733
a3b2jeo.png


Giriş

Merhaba, bugünkü yazımda sizlere AngleSharp ile nasıl web kazıma yapılır onu anlatacağım.
Bu konuyu özellikle seçme sebeplerimden başında Türkiye'de bununla ilgili bir kaynak olmaması yer alıyor.
Bu alanda merakı olanların illa yabancı kaynaklara muhtaç olmasını istemiyorum. Bu yüzden elimden geldiğince detaylı anlatmaya çalışacağım.
Neyse çok uzatmadan konumuza geçelim, iyi okumalar dilerim!

6OfL8I.gif


Kullanım

Öncelikle işe bir proje dosyası oluşturmakla başlayalım.

s4vu87d.png


Ben programın ismini "Web Kazıma Projesi" şeklinde koyuyorum, siz de kendinize göre isimlendirebilirsiniz.

6OfL8I.gif


Projemiz oluştuktan sonra gerekli kütüphanemizi eklememiz gerekiyor.

rwpjwlg.png


Bu işlem için sağ taraftaki "Çözüm Gezgini" kısmından projemizin üstüne sağ tık yapıyoruz ve çıkan kısımdan "NuGet Paketlerini Yönet..." diyoruz.

6OfL8I.gif


bim7bzg.png


Açılan kısımdan "Gözat" kısmına tıklıyoruz ve arama kısmına "AngleSharp" yazıyoruz.
İlk çıkanı seçtikten sonra "Yükle" tuşuna basıyoruz.

6OfL8I.gif


3vdmg3j.png


Kütüphanemiz yüklendikten sonra

C#:
using AngleSharp;
using AngleSharp.Dom;

ile kodumuza dahil ediyoruz.

Kütüphanemizi kodumuza dahil ettikten sonraki işlem ise kazıma yapacağımız sitenin kaynak kodlarını çekmek olacak.
Ben kullanımı daha basit olsun ve anlaşılır olsun diye basit bir site tasarladım ve bunu localhostuma attım.
Bilmeyenler için şu konumdaki eklentinin site hali: Tarayıcılar için Sıfırdan Eklenti Oluşturma!

Sitenin Görünümü

2qphlrl.png


Sizde bu örnek üzerinde işlemek isterseniz..

Sitenin Kaynak Kodları

HTML:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>THT Profiller</title>
</head>
<body>

    <main>
        <a href="https://www.turkhackteam.org/uye/rei-a.879110/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/879/879110.jpg?1661379848" alt="Reina">
                    <font color="#FF000E">
                        <h3 id="ust_duzey_yonetim" class="kullanici_adi">Reina</h3>
                    </font>
                    <p class="rutbe">Administrator</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/grimner.892463/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/892/892463.jpg?1697033887" alt="Grimner">
                    <font color="#008000">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">Grimner</h3>
                    </font>
                    <p class="rutbe">Deneyimli Moderatör</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/ra.766994/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/766/766994.jpg?1702546219" alt="'Ra">
                    <font color="#008000">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">'Ra</h3>
                    </font>
                    <p class="rutbe">Ticaret Kategorisi <br> Sorumlu Yrd.</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/kruvazor.892346/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/892/892346.jpg?1702285052" alt="Kruvazör">
                    <font color="#84D2FF">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">Kruvazör</h3>
                    </font>
                    <p class="rutbe">Global Moderatör</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/pump.988625/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/988/988625.jpg?1701366802" alt="'pump">
                    <font color="#FFFFFFF">
                        <h3 id="normal_uye" class="kullanici_adi">'pump</h3>
                    </font>
                    <p class="rutbe">Uzman Üye</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/teux.993846/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/993/993846.jpg?1701983064" alt="teux">
                    <font color="#FFFFFFF">
                        <h3 id="normal_uye" class="kullanici_adi">teux</h3>
                    </font>
                    <p class="rutbe">Katılımcı Üye</p>
                </center>
            </div>
        </a>
    </main>

<style>
    main {
        position: absolute;
        left: 50%;
        Top: 50%;
        transform: translate(-50%, -50%);
        margin-top: -100px;
        width: 1200px;
        height: 100px;
    }
    body {
        margin: 0;
        padding: 0;
        background: url(https://i.hizliresim.com/g6aa7R.jpg);
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        height: 100vh;
    }
    .uye {
        float: left;
        width: 180px;
        height: 250px;
        background: yellowgreen;
        background: rgba(0, 0, 0, 0.6);
        border-radius: 5px;
        margin: 10px;
    }
    .profil_resmi {
        width: 150px;
        height: 150px;
        margin-top: 10px;
        border-radius: 5px;
    }
    .kullanici_adi {
        margin-top: 2px;
    }
    .rutbe {
        color: white;
        margin-top: -15px;
    }
</style>
</body>
</html>

6OfL8I.gif


Evet, sitemiz belli olduğuna göre kaynak kodlarını çekmeye gelelim.
Bunun için kullanacağımız kod

C#:
string Url = "http://localhost/THTProfiller/";
// Kazıma yapacağımız sitenin adresi. Http olmasına dikkat yoksa hata veriyor..

HttpClient Client = new HttpClient();
// Burada bir http kullanıcısı oluşturuyoruz.

string Html = Client.GetStringAsync(Url).Result;
// Burada urlden dönen sonucu alıyoruz ki burası front end tarafın kaynak kodları oluyor.

Kaynak kodlarımızı çektiğimize göre yavaştan kazıma işlemlerine geçebiliriz.

6OfL8I.gif


Benim bu derste anlatacağım yapılar aşağıdaki sırayla olacak.
Başlık Kazıma
Yazı Kazıma
Link Adresi Kazıma
Resim Kaynağı Kazıma
Alt Etiketi Kazıma
Renk Kazıma
ID ve Class İşlemleri
ID ve Class Filtreleme
Çocuk (Child) İşlemleri
Ebebeyn (Parent) İşlemleri
Kardeş (Siblings) İşlemleri​

Öncelikle kazıma işlemine başlamadan iki satır değişmeyecek kodlarımız var onları yazalım.

C#:
var Parser = new HtmlParser();
// Bu kodumuzu Html belgelerini ayrıştırmak için kullanıyoruz.

var Document = Parser.ParseDocument(Html);
// Buradaki değişkenimize ayrıştırdığımız html etiketlerini atıyoruz.

6OfL8I.gif


Evet, Html belgemizi ayrıştırdığımıza göre başlığımızı kazımakla devam edelim.
Bunun için iki farklı yolumuz mevcut birisi sadece başlığı çekmeye yararken diğerini tüm Html etiketleri için kullanabiliyoruz.

Öncelikle başlığa özel koda bakalım.

C#:
var Title = Document.Title;

Evet, bu yolumuzda Document'in içinden ayrıştırılmış başlığı direkt çektik.
Şimdi de tüm Html etiketlerinin içinden veri çekmemize ve daha çok kullanacağımız yönteme geçelim.

C#:
var Title = Document.QuerySelector("title").TextContent;

s1eizuo.png


6OfL8I.gif


Bu yöntem de etiketi buluyor ve içindeki değeri ekrana yazdırıyor.
Başlık yazdırma işlemimiz kısaca bu kadardı.
Şimdi yazı etiketlerimizi yazdırmaya bakalım. Aslında bunda da mantık oldukça benzer.
Hatta değişen tek şey etiket ismi diyebiliriz.

njgksxr.png


Benim size verdiğim kodu incelediğimizde 2 farklı yazı etiketi görüyoruz. (a hariç..)
Bunlardan birisi başlık etiketi h3 birisi ise paragraf etiketi p.
Öncelikle ben h3 olan etiketin içindeki yazdırmak istiyorum diyelim.
Bunun için kullanmam gereken kod aşağıdaki gibi olacaktır.

C#:
var H3 = Document.QuerySelector("h3").TextContent;

Bu kodu ekrana yazdırmak için ise

C#:
Console.WriteLine(H3);

Bu arada buradaki TextContent kısmını illa değişkeni tanımlarken girmenize gerek yok.

C#:
var H3 = Document.QuerySelector("h3");
Console.WriteLine(H3.TextContent);

Şeklinde de kullanılabilir.

t66e6cn.png


Evet, genel olarak etiket içindeki değerleri kazıma işlemi bu kadardı.
Şimdi ise programımızı çalıştıralım ve sonuca bakalım.

m5d1paq.png


Gördüğünüz gibi program çalıştığında ekrana "Reina" yazısı geldi.

Peki neden Grimner, 'Ra veya 'pump değil de Reina?
Aslında bunun sebebi basit. Biz özel bir koşul belirtmedikçe, belirtilen etiket arasında ki ilkini seçer ve ekrana yazdırır.
ID ve Class kısmında filtreleme mantığını anlatınca daha iyi anlarsınız..

Peki sadece Reina yazdırmak yerine hepsini yazdırmak istersek ne yapacağız?
Bunun için kullandığımız kodda bir iki değişiklik yapmamız gerekmekte.

Mesela QuerySelector kısmını QuerySelectorAll şeklinde değiştirmek gibi.
Bu sayede artık ilk baştaki etiketi değil, tüm etiketleri almış olacağız.
Bu aldığımız etiketlerin tamamını ekrana yazdırmak için ise foreach döngüsü kullanabiliriz.

C#:
string Url = "http://localhost/THTProfiller/";
HttpClient Client = new HttpClient();
string Html = Client.GetStringAsync(Url).Result;

var Parser = new HtmlParser();
var Document = Parser.ParseDocument(Html);

var H3s = Document.QuerySelectorAll("h3");

foreach (var H3 in H3s)
{
    Console.WriteLine(H3.TextContent);
}

Console.ReadKey();

chtaaom.png


Gördüğünüz gibi h3 etiketlerimizin içindeki tüm değerler ekrana yazdırıldı.
Bu işlemin aynısını <p> etiketi içinde yapabilirsiniz, ben şu an konu da aşırı resim kalabalığı olmasın diye her birini tek tek göstermeyeceğim.
Her birini görmek isterseniz yazının sonundaki videolu kaynağa bakabilirsiniz.
(Video küçük bir sıkıntıdan dolayı sonradan eklenecek..)

6OfL8I.gif


Yazı kazıma işlemimiz bittiğine göre şimdi diğer bir işlemimiz olan öznitelik almaya geçebiliriz.
Bu işlem sayesinde link, src, alt, color kazıma gibi işlemler yapabiliyoruz.

Öncelikle link kazıma ile başlayalım isterseniz.
Bunun için TextContent kısmını GetAttribute("") ile değiştirmemiz gerekiyor.
Bu şekilde etiketlerimizin özelliklerini alabiliyoruz.
Örneğin a etiketimizin içindeki linki almak istiyorsak GetAttribute("") içine linki barındıran öznitelik olan hrefi yazmamız gerek.

Buna göre kodumuzun alacağı son hal şu şekilde olacaktır.

C#:
var Links = Document.QuerySelectorAll("a");

foreach (var Link in Links)
{
    Console.WriteLine(Link.GetAttribute("href"));
}

2a4wg64.png


Konunun çok uzamaması için aşırı üzerinde durmayacak olsam da diğer öznitelik kullanımları da aşağıdaki gibidir.

C#:
Console.WriteLine(Color.GetAttribute("color"));
// Renk kazıma.

Console.WriteLine(Alt.GetAttribute("alt"));
// Alt kazıma.

Console.WriteLine(Source.GetAttribute("src"));
// Resim kaynağı kazıma.

Tabi ben burada 3 tane ekledim. Siz bunları "style, width, height, border" tarzında çeşitlendirebilirsiniz.

6OfL8I.gif


Evet, öznitelik kazıma kısmı da bu kadardı.
Şimdi ID ve Class alma sonrada Filtreleme yapma işlemlerine bakalım.

ID ve Class alırken bir kaç farklı yolla alabiliyoruz.
İlk olarak Id ve ClassName özellikleri ile.

C#:
var Class = Document.QuerySelector("a").ClassName;
// Bu kodumuzda ilk a etiketimizin class isimlerini alıyor.

var Id = Document.QuerySelector("a").Id;
// Burada ise ilk a etiketimizin id değerlerini alıyor.

// Tabi benim size verdiğim kod üzerinde denerseniz ekrana herhangi bir çıktı vermez çünkü <a> etiketi içinde id veya class yok :D
// H3 ile çıktı alırsınız ama..

Şimdi ID ve Class kullanımımızın farklı bir türüne bakalım.
Bu seferki işlemimizi QuerySelector ile yapacağız.
ID araması başına yaparken # Class araması yaparken . koymalısınız.

C#:
var Class = Document.QuerySelectorAll(".kullanici_adi");
// Burada class'ı kullanici_adi olan tüm etiletleri alıyoruz.
// Çıkacak sonuç: Reina, Grimner, 'Ra, Kruvazör, 'pump, teux

var Id = Document.QuerySelectorAll("#ust_duzey_yonetim");
// Burada id'si ust_duzey_yonetim olan etiketleri alıyoruz.
// Sonuç: Reina

Şimdi de filtreleme işlemimize bakalım ve bu kısmı da geçelim.

C#:
 var H3s = Document.QuerySelectorAll("h3");
// Buradan tüm <h3> etiketlerini alıyoruz.

foreach (var H3 in H3s)
{
    if (H3.Id == "normal_uye") // Burada ise Id'sinin normal_uye olup olmadığını kontrol ediyor.
        Console.WriteLine(H3.TextContent); // Eğer filtreleme işleminden geçerse ekrana yazdırıyor.
}

Bu yöntem dışında öznitelik ile de filtreleme işlemi yapılabilir.

C#:
var H3s = Document.QuerySelectorAll("h3");

foreach (var H3 in H3s)
{
    if (H3.GetAttribute("id") == "normal_uye")
        Console.WriteLine(H3);
}

Burada seçim biraz da size kalıyor. Tabi Title, Id ve Class gibi belirli şeyler dışında GetAttribute kullanılması gerekiyor.

6OfL8I.gif


Evet, bunlarda bittiğine göre Child kısmına geçebiliriz.
Child kavramını bilmeyenler için çocuk demek.
Mesela size verdiğim koda bakarsak

HTML:
<font color="#FF000E">
    <h3 id="ust_duzey_yonetim" class="kullanici_adi">Reina</h3>
    <h3 id="alt_duzey_yonetim" class="kullanici_adi">Grimner</h3>
    <h3 id="normal_uye" class="kullanici_adi">Pump</h3>
</font>

Burada <h3>'ler, <font> etiketinin içinde oldukları için onun çocuğu oluyor.
Mesela ben bunların içindeki ilkini ekrana yazdırmak istiyorum diyelim.
Bunun için FirstElementChild kodunu kullanmam gerek.

C#:
var font = Document.QuerySelector("font");
Console.WriteLine(font.FirstElementChild.TextContent);

Bunun sonucunda ekrana "Reina" diye çıktı verecektir.
Bir de sondaki child'i yazdırmak istiyorum diyelim.
Bunun için de LastElementChild kullanmam gerekir.

C#:
var font = Document.QuerySelector("font");
Console.WriteLine(font.LastElementChild.TextContent);

Bu seferde son etiket Pump olduğu için ekrana Pump diye yazdıracak.
Ben bunların hiçbirini istemiyorum index ile yapayım diyorsanız da, Children[] kullanmanız gerek.
Örneğin ben ikinci <h3> etiketini yazdırmak istiyorum.
Bunun için kullanmam gereken kod şu:

C#:
Console.WriteLine(font.Children[1].TextContent);

Child kısmında göreceğimiz son şey ise Child sayısını almak.
Yukarıdaki html örneğimizde font içinde 3 tane h3 vardı.
Bunun sayısını almak ve ekrana yazdırmak için kullanmamız gereken kod:

C#:
 var font = Document.QuerySelector("font");
Console.WriteLine(font.ChildElementCount);

6OfL8I.gif


Evet, Child işlemleri bu kadardı.
Şimdi Siblings kullanımına bakalım.
Bu özellik sayesinde bir sonraki etikete hükmedebiliyoruz.
Mesela ben bir sonraki etiketin içindeki değeri ekrana yazdırmak istiyorum.
Bunun için kullanacağım kod:

C#:
var h3 = Document.QuerySelector("h3");
// Bu kod ile ilk h3 etiketini aldım (Reina yazan).

Console.WriteLine(h3.NextElementSibling.TextContent);
Bununla da 'Reina' yazandan bir sonrakini ekrana yazdırıyorum. Yani ekrana 'Grimner' diye yazdıracak.

6OfL8I.gif


Siblings de temel olarak bu kadardı. Şimdi son olarak Parent kısmına bakalım ve konumuzu bitirelim.
Parent kısmında da pek bir şey yok aslında. Sadece belirttiğimiz etiketin üstündeki etiketi bize bildiriyor.
Mesela ben h3 etiketimin parentini öğrenmek istiyorum.
Bunun için kullanacağım kod:

C#:
var h3 = Document.QuerySelector("h3");
Console.WriteLine(h3.ParentElement.LocalName);

6OfL8I.gif


Kapanış

Evet, yazımız bu kadardı.
Elbette anlatmadığım kısımlar ve detaylar var ancak konu bu haliyle bile bayağı bir uzun oldu zaten..
Gelecek yazılarımda bu kütüphaneyi kullanarak gerçek sitelerden veri çeken araçlarda yazarız.
Okuduğunuz için teşekkür ederim, iyi forumlar!​
 

drjacob

Uzman üye
21 Ocak 2012
1,778
406
localhost
a3b2jeo.png


Giriş

Merhaba, bugünkü yazımda sizlere AngleSharp ile nasıl web kazıma yapılır onu anlatacağım.
Bu konuyu özellikle seçme sebeplerimden başında Türkiye'de bununla ilgili bir kaynak olmaması yer alıyor.
Bu alanda merakı olanların illa yabancı kaynaklara muhtaç olmasını istemiyorum. Bu yüzden elimden geldiğince detaylı anlatmaya çalışacağım.
Neyse çok uzatmadan konumuza geçelim, iyi okumalar dilerim!

6OfL8I.gif


Kullanım

Öncelikle işe bir proje dosyası oluşturmakla başlayalım.

s4vu87d.png


Ben programın ismini "Web Kazıma Projesi" şeklinde koyuyorum, siz de kendinize göre isimlendirebilirsiniz.

6OfL8I.gif


Projemiz oluştuktan sonra gerekli kütüphanemizi eklememiz gerekiyor.

rwpjwlg.png


Bu işlem için sağ taraftaki "Çözüm Gezgini" kısmından projemizin üstüne sağ tık yapıyoruz ve çıkan kısımdan "NuGet Paketlerini Yönet..." diyoruz.

6OfL8I.gif


bim7bzg.png


Açılan kısımdan "Gözat" kısmına tıklıyoruz ve arama kısmına "AngleSharp" yazıyoruz.
İlk çıkanı seçtikten sonra "Yükle" tuşuna basıyoruz.

6OfL8I.gif


3vdmg3j.png


Kütüphanemiz yüklendikten sonra

C#:
using AngleSharp;
using AngleSharp.Dom;

ile kodumuza dahil ediyoruz.

Kütüphanemizi kodumuza dahil ettikten sonraki işlem ise kazıma yapacağımız sitenin kaynak kodlarını çekmek olacak.
Ben kullanımı daha basit olsun ve anlaşılır olsun diye basit bir site tasarladım ve bunu localhostuma attım.
Bilmeyenler için şu konumdaki eklentinin site hali: Tarayıcılar için Sıfırdan Eklenti Oluşturma!

Sitenin Görünümü

2qphlrl.png


Sizde bu örnek üzerinde işlemek isterseniz..

Sitenin Kaynak Kodları

HTML:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>THT Profiller</title>
</head>
<body>

    <main>
        <a href="https://www.turkhackteam.org/uye/rei-a.879110/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/879/879110.jpg?1661379848" alt="Reina">
                    <font color="#FF000E">
                        <h3 id="ust_duzey_yonetim" class="kullanici_adi">Reina</h3>
                    </font>
                    <p class="rutbe">Administrator</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/grimner.892463/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/892/892463.jpg?1697033887" alt="Grimner">
                    <font color="#008000">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">Grimner</h3>
                    </font>
                    <p class="rutbe">Deneyimli Moderatör</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/ra.766994/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/766/766994.jpg?1702546219" alt="'Ra">
                    <font color="#008000">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">'Ra</h3>
                    </font>
                    <p class="rutbe">Ticaret Kategorisi <br> Sorumlu Yrd.</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/kruvazor.892346/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/892/892346.jpg?1702285052" alt="Kruvazör">
                    <font color="#84D2FF">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">Kruvazör</h3>
                    </font>
                    <p class="rutbe">Global Moderatör</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/pump.988625/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/988/988625.jpg?1701366802" alt="'pump">
                    <font color="#FFFFFFF">
                        <h3 id="normal_uye" class="kullanici_adi">'pump</h3>
                    </font>
                    <p class="rutbe">Uzman Üye</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/teux.993846/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/993/993846.jpg?1701983064" alt="teux">
                    <font color="#FFFFFFF">
                        <h3 id="normal_uye" class="kullanici_adi">teux</h3>
                    </font>
                    <p class="rutbe">Katılımcı Üye</p>
                </center>
            </div>
        </a>
    </main>

<style>
    main {
        position: absolute;
        left: 50%;
        Top: 50%;
        transform: translate(-50%, -50%);
        margin-top: -100px;
        width: 1200px;
        height: 100px;
    }
    body {
        margin: 0;
        padding: 0;
        background: url(https://i.hizliresim.com/g6aa7R.jpg);
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        height: 100vh;
    }
    .uye {
        float: left;
        width: 180px;
        height: 250px;
        background: yellowgreen;
        background: rgba(0, 0, 0, 0.6);
        border-radius: 5px;
        margin: 10px;
    }
    .profil_resmi {
        width: 150px;
        height: 150px;
        margin-top: 10px;
        border-radius: 5px;
    }
    .kullanici_adi {
        margin-top: 2px;
    }
    .rutbe {
        color: white;
        margin-top: -15px;
    }
</style>
</body>
</html>

6OfL8I.gif


Evet, sitemiz belli olduğuna göre kaynak kodlarını çekmeye gelelim.
Bunun için kullanacağımız kod

C#:
string Url = "http://localhost/THTProfiller/";
// Kazıma yapacağımız sitenin adresi. Http olmasına dikkat yoksa hata veriyor..

HttpClient Client = new HttpClient();
// Burada bir http kullanıcısı oluşturuyoruz.

string Html = Client.GetStringAsync(Url).Result;
// Burada urlden dönen sonucu alıyoruz ki burası front end tarafın kaynak kodları oluyor.

Kaynak kodlarımızı çektiğimize göre yavaştan kazıma işlemlerine geçebiliriz.

6OfL8I.gif


Benim bu derste anlatacağım yapılar aşağıdaki sırayla olacak.



Öncelikle kazıma işlemine başlamadan iki satır değişmeyecek kodlarımız var onları yazalım.

C#:
var Parser = new HtmlParser();
// Bu kodumuzu Html belgelerini ayrıştırmak için kullanıyoruz.

var Document = Parser.ParseDocument(Html);
// Buradaki değişkenimize ayrıştırdığımız html etiketlerini atıyoruz.

6OfL8I.gif


Evet, Html belgemizi ayrıştırdığımıza göre başlığımızı kazımakla devam edelim.
Bunun için iki farklı yolumuz mevcut birisi sadece başlığı çekmeye yararken diğerini tüm Html etiketleri için kullanabiliyoruz.

Öncelikle başlığa özel koda bakalım.

C#:
var Title = Document.Title;

Evet, bu yolumuzda Document'in içinden ayrıştırılmış başlığı direkt çektik.
Şimdi de tüm Html etiketlerinin içinden veri çekmemize ve daha çok kullanacağımız yönteme geçelim.

C#:
var Title = Document.QuerySelector("title").TextContent;

s1eizuo.png


6OfL8I.gif


Bu yöntem de etiketi buluyor ve içindeki değeri ekrana yazdırıyor.
Başlık yazdırma işlemimiz kısaca bu kadardı.
Şimdi yazı etiketlerimizi yazdırmaya bakalım. Aslında bunda da mantık oldukça benzer.
Hatta değişen tek şey etiket ismi diyebiliriz.

njgksxr.png


Benim size verdiğim kodu incelediğimizde 2 farklı yazı etiketi görüyoruz. (a hariç..)
Bunlardan birisi başlık etiketi h3 birisi ise paragraf etiketi p.
Öncelikle ben h3 olan etiketin içindeki yazdırmak istiyorum diyelim.
Bunun için kullanmam gereken kod aşağıdaki gibi olacaktır.

C#:
var H3 = Document.QuerySelector("h3").TextContent;

Bu kodu ekrana yazdırmak için ise

C#:
Console.WriteLine(H3);

Bu arada buradaki TextContent kısmını illa değişkeni tanımlarken girmenize gerek yok.

C#:
var H3 = Document.QuerySelector("h3");
Console.WriteLine(H3.TextContent);

Şeklinde de kullanılabilir.

t66e6cn.png


Evet, genel olarak etiket içindeki değerleri kazıma işlemi bu kadardı.
Şimdi ise programımızı çalıştıralım ve sonuca bakalım.

m5d1paq.png


Gördüğünüz gibi program çalıştığında ekrana "Reina" yazısı geldi.

Peki neden Grimner, 'Ra veya 'pump değil de Reina?
Aslında bunun sebebi basit. Biz özel bir koşul belirtmedikçe, belirtilen etiket arasında ki ilkini seçer ve ekrana yazdırır.
ID ve Class kısmında filtreleme mantığını anlatınca daha iyi anlarsınız..

Peki sadece Reina yazdırmak yerine hepsini yazdırmak istersek ne yapacağız?
Bunun için kullandığımız kodda bir iki değişiklik yapmamız gerekmekte.

Mesela QuerySelector kısmını QuerySelectorAll şeklinde değiştirmek gibi.
Bu sayede artık ilk baştaki etiketi değil, tüm etiketleri almış olacağız.
Bu aldığımız etiketlerin tamamını ekrana yazdırmak için ise foreach döngüsü kullanabiliriz.

C#:
string Url = "http://localhost/THTProfiller/";
HttpClient Client = new HttpClient();
string Html = Client.GetStringAsync(Url).Result;

var Parser = new HtmlParser();
var Document = Parser.ParseDocument(Html);

var H3s = Document.QuerySelectorAll("h3");

foreach (var H3 in H3s)
{
    Console.WriteLine(H3.TextContent);
}

Console.ReadKey();

chtaaom.png


Gördüğünüz gibi h3 etiketlerimizin içindeki tüm değerler ekrana yazdırıldı.
Bu işlemin aynısını <p> etiketi içinde yapabilirsiniz, ben şu an konu da aşırı resim kalabalığı olmasın diye her birini tek tek göstermeyeceğim.
Her birini görmek isterseniz yazının sonundaki videolu kaynağa bakabilirsiniz.
(Video küçük bir sıkıntıdan dolayı sonradan eklenecek..)

6OfL8I.gif


Yazı kazıma işlemimiz bittiğine göre şimdi diğer bir işlemimiz olan öznitelik almaya geçebiliriz.
Bu işlem sayesinde link, src, alt, color kazıma gibi işlemler yapabiliyoruz.

Öncelikle link kazıma ile başlayalım isterseniz.
Bunun için TextContent kısmını GetAttribute("") ile değiştirmemiz gerekiyor.
Bu şekilde etiketlerimizin özelliklerini alabiliyoruz.
Örneğin a etiketimizin içindeki linki almak istiyorsak GetAttribute("") içine linki barındıran öznitelik olan hrefi yazmamız gerek.

Buna göre kodumuzun alacağı son hal şu şekilde olacaktır.

C#:
var Links = Document.QuerySelectorAll("a");

foreach (var Link in Links)
{
    Console.WriteLine(Link.GetAttribute("href"));
}

2a4wg64.png


Konunun çok uzamaması için aşırı üzerinde durmayacak olsam da diğer öznitelik kullanımları da aşağıdaki gibidir.

C#:
Console.WriteLine(Color.GetAttribute("color"));
// Renk kazıma.

Console.WriteLine(Alt.GetAttribute("alt"));
// Alt kazıma.

Console.WriteLine(Source.GetAttribute("src"));
// Resim kaynağı kazıma.

Tabi ben burada 3 tane ekledim. Siz bunları "style, width, height, border" tarzında çeşitlendirebilirsiniz.

6OfL8I.gif


Evet, öznitelik kazıma kısmı da bu kadardı.
Şimdi ID ve Class alma sonrada Filtreleme yapma işlemlerine bakalım.

ID ve Class alırken bir kaç farklı yolla alabiliyoruz.
İlk olarak Id ve ClassName özellikleri ile.

C#:
var Class = Document.QuerySelector("a").ClassName;
// Bu kodumuzda ilk a etiketimizin class isimlerini alıyor.

var Id = Document.QuerySelector("a").Id;
// Burada ise ilk a etiketimizin id değerlerini alıyor.

// Tabi benim size verdiğim kod üzerinde denerseniz ekrana herhangi bir çıktı vermez çünkü <a> etiketi içinde id veya class yok :D
// H3 ile çıktı alırsınız ama..

Şimdi ID ve Class kullanımımızın farklı bir türüne bakalım.
Bu seferki işlemimizi QuerySelector ile yapacağız.
ID araması başına yaparken # Class araması yaparken . koymalısınız.

C#:
var Class = Document.QuerySelectorAll(".kullanici_adi");
// Burada class'ı kullanici_adi olan tüm etiletleri alıyoruz.
// Çıkacak sonuç: Reina, Grimner, 'Ra, Kruvazör, 'pump, teux

var Id = Document.QuerySelectorAll("#ust_duzey_yonetim");
// Burada id'si ust_duzey_yonetim olan etiketleri alıyoruz.
// Sonuç: Reina

Şimdi de filtreleme işlemimize bakalım ve bu kısmı da geçelim.

C#:
 var H3s = Document.QuerySelectorAll("h3");
// Buradan tüm <h3> etiketlerini alıyoruz.

foreach (var H3 in H3s)
{
    if (H3.Id == "normal_uye") // Burada ise Id'sinin normal_uye olup olmadığını kontrol ediyor.
        Console.WriteLine(H3.TextContent); // Eğer filtreleme işleminden geçerse ekrana yazdırıyor.
}

Bu yöntem dışında öznitelik ile de filtreleme işlemi yapılabilir.

C#:
var H3s = Document.QuerySelectorAll("h3");

foreach (var H3 in H3s)
{
    if (H3.GetAttribute("id") == "normal_uye")
        Console.WriteLine(H3);
}

Burada seçim biraz da size kalıyor. Tabi Title, Id ve Class gibi belirli şeyler dışında GetAttribute kullanılması gerekiyor.

6OfL8I.gif


Evet, bunlarda bittiğine göre Child kısmına geçebiliriz.
Child kavramını bilmeyenler için çocuk demek.
Mesela size verdiğim koda bakarsak

HTML:
<font color="#FF000E">
    <h3 id="ust_duzey_yonetim" class="kullanici_adi">Reina</h3>
    <h3 id="alt_duzey_yonetim" class="kullanici_adi">Grimner</h3>
    <h3 id="normal_uye" class="kullanici_adi">Pump</h3>
</font>

Burada <h3>'ler, <font> etiketinin içinde oldukları için onun çocuğu oluyor.
Mesela ben bunların içindeki ilkini ekrana yazdırmak istiyorum diyelim.
Bunun için FirstElementChild kodunu kullanmam gerek.

C#:
var font = Document.QuerySelector("font");
Console.WriteLine(font.FirstElementChild.TextContent);

Bunun sonucunda ekrana "Reina" diye çıktı verecektir.
Bir de sondaki child'i yazdırmak istiyorum diyelim.
Bunun için de LastElementChild kullanmam gerekir.

C#:
var font = Document.QuerySelector("font");
Console.WriteLine(font.LastElementChild.TextContent);

Bu seferde son etiket Pump olduğu için ekrana Pump diye yazdıracak.
Ben bunların hiçbirini istemiyorum index ile yapayım diyorsanız da, Children[] kullanmanız gerek.
Örneğin ben ikinci <h3> etiketini yazdırmak istiyorum.
Bunun için kullanmam gereken kod şu:

C#:
Console.WriteLine(font.Children[1].TextContent);

Child kısmında göreceğimiz son şey ise Child sayısını almak.
Yukarıdaki html örneğimizde font içinde 3 tane h3 vardı.
Bunun sayısını almak ve ekrana yazdırmak için kullanmamız gereken kod:

C#:
 var font = Document.QuerySelector("font");
Console.WriteLine(font.ChildElementCount);

6OfL8I.gif


Evet, Child işlemleri bu kadardı.
Şimdi Siblings kullanımına bakalım.
Bu özellik sayesinde bir sonraki etikete hükmedebiliyoruz.
Mesela ben bir sonraki etiketin içindeki değeri ekrana yazdırmak istiyorum.
Bunun için kullanacağım kod:

C#:
var h3 = Document.QuerySelector("h3");
// Bu kod ile ilk h3 etiketini aldım (Reina yazan).

Console.WriteLine(h3.NextElementSibling.TextContent);
Bununla da 'Reina' yazandan bir sonrakini ekrana yazdırıyorum. Yani ekrana 'Grimner' diye yazdıracak.

6OfL8I.gif


Siblings de temel olarak bu kadardı. Şimdi son olarak Parent kısmına bakalım ve konumuzu bitirelim.
Parent kısmında da pek bir şey yok aslında. Sadece belirttiğimiz etiketin üstündeki etiketi bize bildiriyor.
Mesela ben h3 etiketimin parentini öğrenmek istiyorum.
Bunun için kullanacağım kod:

C#:
var h3 = Document.QuerySelector("h3");
Console.WriteLine(h3.ParentElement.LocalName);

6OfL8I.gif


Kapanış

Evet, yazımız bu kadardı.
Elbette anlatmadığım kısımlar ve detaylar var ancak konu bu haliyle bile bayağı bir uzun oldu zaten..
Gelecek yazılarımda bu kütüphaneyi kullanarak gerçek sitelerden veri çeken araçlarda yazarız.
Okuduğunuz için teşekkür ederim, iyi forumlar!​
eline sağlık
 

teux

Katılımcı Üye
23 Ocak 2023
959
1,329
a3b2jeo.png


Giriş

Merhaba, bugünkü yazımda sizlere AngleSharp ile nasıl web kazıma yapılır onu anlatacağım.
Bu konuyu özellikle seçme sebeplerimden başında Türkiye'de bununla ilgili bir kaynak olmaması yer alıyor.
Bu alanda merakı olanların illa yabancı kaynaklara muhtaç olmasını istemiyorum. Bu yüzden elimden geldiğince detaylı anlatmaya çalışacağım.
Neyse çok uzatmadan konumuza geçelim, iyi okumalar dilerim!

6OfL8I.gif


Kullanım

Öncelikle işe bir proje dosyası oluşturmakla başlayalım.

s4vu87d.png


Ben programın ismini "Web Kazıma Projesi" şeklinde koyuyorum, siz de kendinize göre isimlendirebilirsiniz.

6OfL8I.gif


Projemiz oluştuktan sonra gerekli kütüphanemizi eklememiz gerekiyor.

rwpjwlg.png


Bu işlem için sağ taraftaki "Çözüm Gezgini" kısmından projemizin üstüne sağ tık yapıyoruz ve çıkan kısımdan "NuGet Paketlerini Yönet..." diyoruz.

6OfL8I.gif


bim7bzg.png


Açılan kısımdan "Gözat" kısmına tıklıyoruz ve arama kısmına "AngleSharp" yazıyoruz.
İlk çıkanı seçtikten sonra "Yükle" tuşuna basıyoruz.

6OfL8I.gif


3vdmg3j.png


Kütüphanemiz yüklendikten sonra

C#:
using AngleSharp;
using AngleSharp.Dom;

ile kodumuza dahil ediyoruz.

Kütüphanemizi kodumuza dahil ettikten sonraki işlem ise kazıma yapacağımız sitenin kaynak kodlarını çekmek olacak.
Ben kullanımı daha basit olsun ve anlaşılır olsun diye basit bir site tasarladım ve bunu localhostuma attım.
Bilmeyenler için şu konumdaki eklentinin site hali: Tarayıcılar için Sıfırdan Eklenti Oluşturma!

Sitenin Görünümü

2qphlrl.png


Sizde bu örnek üzerinde işlemek isterseniz..

Sitenin Kaynak Kodları

HTML:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>THT Profiller</title>
</head>
<body>

    <main>
        <a href="https://www.turkhackteam.org/uye/rei-a.879110/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/879/879110.jpg?1661379848" alt="Reina">
                    <font color="#FF000E">
                        <h3 id="ust_duzey_yonetim" class="kullanici_adi">Reina</h3>
                    </font>
                    <p class="rutbe">Administrator</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/grimner.892463/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/892/892463.jpg?1697033887" alt="Grimner">
                    <font color="#008000">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">Grimner</h3>
                    </font>
                    <p class="rutbe">Deneyimli Moderatör</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/ra.766994/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/766/766994.jpg?1702546219" alt="'Ra">
                    <font color="#008000">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">'Ra</h3>
                    </font>
                    <p class="rutbe">Ticaret Kategorisi <br> Sorumlu Yrd.</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/kruvazor.892346/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/892/892346.jpg?1702285052" alt="Kruvazör">
                    <font color="#84D2FF">
                        <h3 id="alt_duzey_yonetim" class="kullanici_adi">Kruvazör</h3>
                    </font>
                    <p class="rutbe">Global Moderatör</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/pump.988625/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/988/988625.jpg?1701366802" alt="'pump">
                    <font color="#FFFFFFF">
                        <h3 id="normal_uye" class="kullanici_adi">'pump</h3>
                    </font>
                    <p class="rutbe">Uzman Üye</p>
                </center>
            </div>
        </a>

        <a href="https://www.turkhackteam.org/uye/teux.993846/">
            <div class="uye">
                <center>
                    <img class="profil_resmi" src="https://www.turkhackteam.org/data/avatars/l/993/993846.jpg?1701983064" alt="teux">
                    <font color="#FFFFFFF">
                        <h3 id="normal_uye" class="kullanici_adi">teux</h3>
                    </font>
                    <p class="rutbe">Katılımcı Üye</p>
                </center>
            </div>
        </a>
    </main>

<style>
    main {
        position: absolute;
        left: 50%;
        Top: 50%;
        transform: translate(-50%, -50%);
        margin-top: -100px;
        width: 1200px;
        height: 100px;
    }
    body {
        margin: 0;
        padding: 0;
        background: url(https://i.hizliresim.com/g6aa7R.jpg);
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        height: 100vh;
    }
    .uye {
        float: left;
        width: 180px;
        height: 250px;
        background: yellowgreen;
        background: rgba(0, 0, 0, 0.6);
        border-radius: 5px;
        margin: 10px;
    }
    .profil_resmi {
        width: 150px;
        height: 150px;
        margin-top: 10px;
        border-radius: 5px;
    }
    .kullanici_adi {
        margin-top: 2px;
    }
    .rutbe {
        color: white;
        margin-top: -15px;
    }
</style>
</body>
</html>

6OfL8I.gif


Evet, sitemiz belli olduğuna göre kaynak kodlarını çekmeye gelelim.
Bunun için kullanacağımız kod

C#:
string Url = "http://localhost/THTProfiller/";
// Kazıma yapacağımız sitenin adresi. Http olmasına dikkat yoksa hata veriyor..

HttpClient Client = new HttpClient();
// Burada bir http kullanıcısı oluşturuyoruz.

string Html = Client.GetStringAsync(Url).Result;
// Burada urlden dönen sonucu alıyoruz ki burası front end tarafın kaynak kodları oluyor.

Kaynak kodlarımızı çektiğimize göre yavaştan kazıma işlemlerine geçebiliriz.

6OfL8I.gif


Benim bu derste anlatacağım yapılar aşağıdaki sırayla olacak.



Öncelikle kazıma işlemine başlamadan iki satır değişmeyecek kodlarımız var onları yazalım.

C#:
var Parser = new HtmlParser();
// Bu kodumuzu Html belgelerini ayrıştırmak için kullanıyoruz.

var Document = Parser.ParseDocument(Html);
// Buradaki değişkenimize ayrıştırdığımız html etiketlerini atıyoruz.

6OfL8I.gif


Evet, Html belgemizi ayrıştırdığımıza göre başlığımızı kazımakla devam edelim.
Bunun için iki farklı yolumuz mevcut birisi sadece başlığı çekmeye yararken diğerini tüm Html etiketleri için kullanabiliyoruz.

Öncelikle başlığa özel koda bakalım.

C#:
var Title = Document.Title;

Evet, bu yolumuzda Document'in içinden ayrıştırılmış başlığı direkt çektik.
Şimdi de tüm Html etiketlerinin içinden veri çekmemize ve daha çok kullanacağımız yönteme geçelim.

C#:
var Title = Document.QuerySelector("title").TextContent;

s1eizuo.png


6OfL8I.gif


Bu yöntem de etiketi buluyor ve içindeki değeri ekrana yazdırıyor.
Başlık yazdırma işlemimiz kısaca bu kadardı.
Şimdi yazı etiketlerimizi yazdırmaya bakalım. Aslında bunda da mantık oldukça benzer.
Hatta değişen tek şey etiket ismi diyebiliriz.

njgksxr.png


Benim size verdiğim kodu incelediğimizde 2 farklı yazı etiketi görüyoruz. (a hariç..)
Bunlardan birisi başlık etiketi h3 birisi ise paragraf etiketi p.
Öncelikle ben h3 olan etiketin içindeki yazdırmak istiyorum diyelim.
Bunun için kullanmam gereken kod aşağıdaki gibi olacaktır.

C#:
var H3 = Document.QuerySelector("h3").TextContent;

Bu kodu ekrana yazdırmak için ise

C#:
Console.WriteLine(H3);

Bu arada buradaki TextContent kısmını illa değişkeni tanımlarken girmenize gerek yok.

C#:
var H3 = Document.QuerySelector("h3");
Console.WriteLine(H3.TextContent);

Şeklinde de kullanılabilir.

t66e6cn.png


Evet, genel olarak etiket içindeki değerleri kazıma işlemi bu kadardı.
Şimdi ise programımızı çalıştıralım ve sonuca bakalım.

m5d1paq.png


Gördüğünüz gibi program çalıştığında ekrana "Reina" yazısı geldi.

Peki neden Grimner, 'Ra veya 'pump değil de Reina?
Aslında bunun sebebi basit. Biz özel bir koşul belirtmedikçe, belirtilen etiket arasında ki ilkini seçer ve ekrana yazdırır.
ID ve Class kısmında filtreleme mantığını anlatınca daha iyi anlarsınız..

Peki sadece Reina yazdırmak yerine hepsini yazdırmak istersek ne yapacağız?
Bunun için kullandığımız kodda bir iki değişiklik yapmamız gerekmekte.

Mesela QuerySelector kısmını QuerySelectorAll şeklinde değiştirmek gibi.
Bu sayede artık ilk baştaki etiketi değil, tüm etiketleri almış olacağız.
Bu aldığımız etiketlerin tamamını ekrana yazdırmak için ise foreach döngüsü kullanabiliriz.

C#:
string Url = "http://localhost/THTProfiller/";
HttpClient Client = new HttpClient();
string Html = Client.GetStringAsync(Url).Result;

var Parser = new HtmlParser();
var Document = Parser.ParseDocument(Html);

var H3s = Document.QuerySelectorAll("h3");

foreach (var H3 in H3s)
{
    Console.WriteLine(H3.TextContent);
}

Console.ReadKey();

chtaaom.png


Gördüğünüz gibi h3 etiketlerimizin içindeki tüm değerler ekrana yazdırıldı.
Bu işlemin aynısını <p> etiketi içinde yapabilirsiniz, ben şu an konu da aşırı resim kalabalığı olmasın diye her birini tek tek göstermeyeceğim.
Her birini görmek isterseniz yazının sonundaki videolu kaynağa bakabilirsiniz.
(Video küçük bir sıkıntıdan dolayı sonradan eklenecek..)

6OfL8I.gif


Yazı kazıma işlemimiz bittiğine göre şimdi diğer bir işlemimiz olan öznitelik almaya geçebiliriz.
Bu işlem sayesinde link, src, alt, color kazıma gibi işlemler yapabiliyoruz.

Öncelikle link kazıma ile başlayalım isterseniz.
Bunun için TextContent kısmını GetAttribute("") ile değiştirmemiz gerekiyor.
Bu şekilde etiketlerimizin özelliklerini alabiliyoruz.
Örneğin a etiketimizin içindeki linki almak istiyorsak GetAttribute("") içine linki barındıran öznitelik olan hrefi yazmamız gerek.

Buna göre kodumuzun alacağı son hal şu şekilde olacaktır.

C#:
var Links = Document.QuerySelectorAll("a");

foreach (var Link in Links)
{
    Console.WriteLine(Link.GetAttribute("href"));
}

2a4wg64.png


Konunun çok uzamaması için aşırı üzerinde durmayacak olsam da diğer öznitelik kullanımları da aşağıdaki gibidir.

C#:
Console.WriteLine(Color.GetAttribute("color"));
// Renk kazıma.

Console.WriteLine(Alt.GetAttribute("alt"));
// Alt kazıma.

Console.WriteLine(Source.GetAttribute("src"));
// Resim kaynağı kazıma.

Tabi ben burada 3 tane ekledim. Siz bunları "style, width, height, border" tarzında çeşitlendirebilirsiniz.

6OfL8I.gif


Evet, öznitelik kazıma kısmı da bu kadardı.
Şimdi ID ve Class alma sonrada Filtreleme yapma işlemlerine bakalım.

ID ve Class alırken bir kaç farklı yolla alabiliyoruz.
İlk olarak Id ve ClassName özellikleri ile.

C#:
var Class = Document.QuerySelector("a").ClassName;
// Bu kodumuzda ilk a etiketimizin class isimlerini alıyor.

var Id = Document.QuerySelector("a").Id;
// Burada ise ilk a etiketimizin id değerlerini alıyor.

// Tabi benim size verdiğim kod üzerinde denerseniz ekrana herhangi bir çıktı vermez çünkü <a> etiketi içinde id veya class yok :D
// H3 ile çıktı alırsınız ama..

Şimdi ID ve Class kullanımımızın farklı bir türüne bakalım.
Bu seferki işlemimizi QuerySelector ile yapacağız.
ID araması başına yaparken # Class araması yaparken . koymalısınız.

C#:
var Class = Document.QuerySelectorAll(".kullanici_adi");
// Burada class'ı kullanici_adi olan tüm etiletleri alıyoruz.
// Çıkacak sonuç: Reina, Grimner, 'Ra, Kruvazör, 'pump, teux

var Id = Document.QuerySelectorAll("#ust_duzey_yonetim");
// Burada id'si ust_duzey_yonetim olan etiketleri alıyoruz.
// Sonuç: Reina

Şimdi de filtreleme işlemimize bakalım ve bu kısmı da geçelim.

C#:
 var H3s = Document.QuerySelectorAll("h3");
// Buradan tüm <h3> etiketlerini alıyoruz.

foreach (var H3 in H3s)
{
    if (H3.Id == "normal_uye") // Burada ise Id'sinin normal_uye olup olmadığını kontrol ediyor.
        Console.WriteLine(H3.TextContent); // Eğer filtreleme işleminden geçerse ekrana yazdırıyor.
}

Bu yöntem dışında öznitelik ile de filtreleme işlemi yapılabilir.

C#:
var H3s = Document.QuerySelectorAll("h3");

foreach (var H3 in H3s)
{
    if (H3.GetAttribute("id") == "normal_uye")
        Console.WriteLine(H3);
}

Burada seçim biraz da size kalıyor. Tabi Title, Id ve Class gibi belirli şeyler dışında GetAttribute kullanılması gerekiyor.

6OfL8I.gif


Evet, bunlarda bittiğine göre Child kısmına geçebiliriz.
Child kavramını bilmeyenler için çocuk demek.
Mesela size verdiğim koda bakarsak

HTML:
<font color="#FF000E">
    <h3 id="ust_duzey_yonetim" class="kullanici_adi">Reina</h3>
    <h3 id="alt_duzey_yonetim" class="kullanici_adi">Grimner</h3>
    <h3 id="normal_uye" class="kullanici_adi">Pump</h3>
</font>

Burada <h3>'ler, <font> etiketinin içinde oldukları için onun çocuğu oluyor.
Mesela ben bunların içindeki ilkini ekrana yazdırmak istiyorum diyelim.
Bunun için FirstElementChild kodunu kullanmam gerek.

C#:
var font = Document.QuerySelector("font");
Console.WriteLine(font.FirstElementChild.TextContent);

Bunun sonucunda ekrana "Reina" diye çıktı verecektir.
Bir de sondaki child'i yazdırmak istiyorum diyelim.
Bunun için de LastElementChild kullanmam gerekir.

C#:
var font = Document.QuerySelector("font");
Console.WriteLine(font.LastElementChild.TextContent);

Bu seferde son etiket Pump olduğu için ekrana Pump diye yazdıracak.
Ben bunların hiçbirini istemiyorum index ile yapayım diyorsanız da, Children[] kullanmanız gerek.
Örneğin ben ikinci <h3> etiketini yazdırmak istiyorum.
Bunun için kullanmam gereken kod şu:

C#:
Console.WriteLine(font.Children[1].TextContent);

Child kısmında göreceğimiz son şey ise Child sayısını almak.
Yukarıdaki html örneğimizde font içinde 3 tane h3 vardı.
Bunun sayısını almak ve ekrana yazdırmak için kullanmamız gereken kod:

C#:
 var font = Document.QuerySelector("font");
Console.WriteLine(font.ChildElementCount);

6OfL8I.gif


Evet, Child işlemleri bu kadardı.
Şimdi Siblings kullanımına bakalım.
Bu özellik sayesinde bir sonraki etikete hükmedebiliyoruz.
Mesela ben bir sonraki etiketin içindeki değeri ekrana yazdırmak istiyorum.
Bunun için kullanacağım kod:

C#:
var h3 = Document.QuerySelector("h3");
// Bu kod ile ilk h3 etiketini aldım (Reina yazan).

Console.WriteLine(h3.NextElementSibling.TextContent);
Bununla da 'Reina' yazandan bir sonrakini ekrana yazdırıyorum. Yani ekrana 'Grimner' diye yazdıracak.

6OfL8I.gif


Siblings de temel olarak bu kadardı. Şimdi son olarak Parent kısmına bakalım ve konumuzu bitirelim.
Parent kısmında da pek bir şey yok aslında. Sadece belirttiğimiz etiketin üstündeki etiketi bize bildiriyor.
Mesela ben h3 etiketimin parentini öğrenmek istiyorum.
Bunun için kullanacağım kod:

C#:
var h3 = Document.QuerySelector("h3");
Console.WriteLine(h3.ParentElement.LocalName);

6OfL8I.gif


Kapanış

Evet, yazımız bu kadardı.
Elbette anlatmadığım kısımlar ve detaylar var ancak konu bu haliyle bile bayağı bir uzun oldu zaten..
Gelecek yazılarımda bu kütüphaneyi kullanarak gerçek sitelerden veri çeken araçlarda yazarız.
Okuduğunuz için teşekkür ederim, iyi forumlar!​
Bizim katılımcı üyeyi ordan editlesek buraya gaymamı .D
 

Grimner

Adanmış Üye
28 Mar 2020
6,308
4,733
Teşekkürler.

Çok ayrıntılı bir anlatım olmuş elinize sağlık
Elinize sağlık.
Teşekkür ederim.

Bizim katılımcı üyeyi ordan editlesek buraya gaymamı .D
Denemek lazım tabi, Html'den üstüne çizik atayım bakalım buradan da etki edecek mi 😁
 

aslan aslan

Basın&Medya Ekibi Asistanı
1 Şub 2023
653
248
Eline sağlık güzel çalışma olmuş zaten türkçe kaynakta fazla olmadığı için.


akeat4u.png
 

Grimner

Adanmış Üye
28 Mar 2020
6,308
4,733
Eline sağlık güzel çalışma olmuş zaten türkçe kaynakta fazla olmadığı için.​
Elinize sağlık​
Ellerinize sağlık hocam
Teşekkür ederim.

Elinize sağlık hocam...
Teşekkürler asistanım.

Html agility pack dışında bir parser hem de daha iyi olduğunu iddia ediyor. Güzelmiş denenir.
Normalde ben de Html agility pack kullanıyordum ama bir farklılık yapmak istedim. AngleSharp'ın kullanımı da hoşuma gitti. Maalesef kaynak konusunda sınıfta kalıyor..
Performans testi konusu tatlı olabilirdi.
İyi olabilir aslında, fikir için teşekkürler.
 

'Ra

Ticaret Kategori Sorumlu Yardımcısı
21 Kas 2015
2,396
949
Elinize sağlık hocam çok güzel bir konu olmuş
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.