Twitter

Beraber C# ile bot yapalım (=Web Sitelerinden Veri Çekelim)

Websitelerinden kendi kodumuz ile veri çekelim ve yayınlayalım, ne dersiniz?

Internet sayfalarını kod yardımı ile okuyabilmek ve dönen değerleri kullanabilmek için halihazırda iki adet sınıfımız mevcut:

  • HttpWebRequest
  • HttpWebResponse

Bu iki sınıf da System.Net namespace i altında bulunuyor. Dolayısıyla sayfamızın yukarısına using ifadesini eklemeyi unutmuyoruz.

Neyse öncelikle; sayfayı baştan sona HTML olarak indirip bir string değişken içerisine atacak bir metot yazalım.

private static string BilgiCek(string url)
{
    StringBuilder sb = new StringBuilder();
    byte[] buf = new byte[8192];
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream resStream = response.GetResponseStream();
    string tempString = null;
    int count = 0;
    do
    {
        count = resStream.Read(buf, 0, buf.Length);
        if (count != 0)
        {
            tempString = Encoding.UTF8.GetString(buf, 0, count);
            sb.Append(tempString);
        }
    }
    while (count > 0); // any more data to read?
    return sb.ToString();
}

Bu metotla, sayfayı 8k lık dilimler halinde indiriyoruz. Bazen aynı işi yapan daha kısa bir koda da denk gelebilirsiniz.

private static string BilgiCek(string url)
{
    WebRequest istek = HttpWebRequest.Create(url);
    WebResponse cevap = istek.GetResponse();
    StreamReader donenBilgiler = new StreamReader(cevap.GetResponseStream());
    return donenBilgiler.ReadToEnd();
}

İstediğinizi kullanabilirsiniz. Aralarındaki farkı araştırmak size kalmış.

Şimdi gelelim ana metoda. Önce kendimize bir hedef seçelim. Mesela web sitesinin <title>...</title> bilgisini çekmeye çalışalım.

İstediğimiz bilgiyi okuyamama ihtimaline karşı, kodumuzu önce satır sonu karakterlerinden temizleyelim, sonra da RegExp yardımı ile verimizi çekelim:

while (tumu.IndexOf(Environment.NewLine) > -1)
{
    tumu = tumu.Replace(Environment.NewLine, " ");
}

string title = "";
Match m = Regex.Match(tumu, "<title[^>]*>(.*?)</title>",
 RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);

if (m.Success)
{
 tumu = m.Groups[1].Value;
 title = tumu.Trim();
}

Şimdi de bir örnek yapalım:

static void Main(string[] args)
{
    string url = "http://www.daltinkurt.com/Gunluk/70-Sitenize-URL-kisaltma-servisi-ekleyin.aspx";
    string tumu = BilgiCek(url);

    while (tumu.IndexOf(Environment.NewLine) > -1)
    {
        tumu = tumu.Replace(Environment.NewLine, " ");
    }

    string title = "";
    Match m = Regex.Match(tumu, "<title[^>]*>(.*?)</title>",
        RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);

    if (m.Success)
    {
        tumu = m.Groups[1].Value;
        title = tumu.Trim();
    }
    Console.WriteLine(title);
}

Çıktımız:

 

Şimdi de site içeriğinden bilgi almaya çalışalım.

Örnek sayfamız http://www.mgm.gov.tr/tarim/zirai-rapor.aspx olsun.

<h1> .. </h1> tagi içeriğini okumaya çalışalım. Bunu seçme nedenim; 1) içinde başka tag kullanılmış. 2) 2 satırdan oluşuyor, yani bir adet "yeni satır" karakterini (Environment.Newline) temizlememiz 3) son aşamada da split etmemiz gerekiyor.

Buradan buyrun:

static void Main(string[] args)
{
    string url = "http://www.mgm.gov.tr/tarim/zirai-rapor.aspx";
    string html = BilgiCek(url);

    string tarihStr = @"<h1 id=""sfB"">";

    int pos1 = html.IndexOf(tarihStr);
    int pos2 = html.IndexOf("</h1>", pos1);
    string tarih = html.Substring(pos1, pos2 - pos1);
    tarih = ToClearText(tarih);
    string[] pars = tarih.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
    Console.WriteLine("-> " + pars[0].Trim() + " <-");
    Console.WriteLine("-> " + pars[1].Trim() + " <-");
}

Ekran çıktısı:

Bu yöntem sayesinde, gözünüze kestirdiğiniz bir siteden "isim sözlüğü", "atasözleri", "İngilizce-Türkçe sözlük" gibi hazırlanması aylar alacak bilgileri kısa zamanda toplayabilirsiniz.

Herkese kolay gelsin.


Not: ToClearText(string) metodu da nereden çıktı diyenlere:

public static string ToClearText(string text)
{
    return Regex.Replace(text, @"<(.|\n)*?>", string.Empty);
}

 

Değerlendirme

Yazım dilinin sadeliği ve anlaşılabilirliği Puan: 2,66 (27 oy)
Yazıdaki kodların kalitesi Puan: 3,01 (18 oy)
İhtiyaca cevap verme Puan: 2,65 (17 oy)
Tavsiye edilebilirlik Puan: 2,68 (19 oy)
Genel değerlendirme Puan: 2,75 (18 oy)
Puanlamalar 5 üzerindendir.
  • Site Yorumlarý
  • Facebook Yorumlarý Facebook Yorumlarý
Yeni yorum yaz Toplam: 7, Onay bekleyen: 0.
  1. Sait

    ASPX ile hazırlanmış b2b sitesinde verileri çekecek bir bot lazım... böyle bir bot yazdınız mı hiç...?

  2. Mext

    Hocam acaba bir siteden buton ile gönderilen sonucun çıktısını çekebilir miyiz? Yani verilerin girilip sorgu gönderildiği ve sonuç döndürdüğü yeri, biz kendi sitemizde verileri gireceğiz ve butona basınca o sitenin butonuyla oluşan sonucu döndürecek. Bunu yapmanın bir yolu var mı?

    • Devrim Altınkurt

      watin.org a göz atmanı tavsiye ederim.

  3. Halit YILMAZ

    Çok bilgilendirici bir paylaşım olmuş teşekkür ederim. Benim merak ettiğim bir şey var. img tagı içerisindeki parametre değerlerini nasıl alabiliriz. Örneğin SRC ve ALT parametrelerinin değerlerini bu yöntemle çekebilir miyiz? Teşekkür ederim.

  4. Tuba DEMİR

    Çok yardımı oldu, teşekkürler.

  5. Devrim Altınkurt

    tabii ki, regexp ile yapabilirsin. google da aratınca karşına çıkan herhangi bir regexp i kullanabilirsin. örnek: <img\s+[^>]*?\bsrc=\`[^\`]*?\`[^>]*>