Ana içeriğe atla

Bir Web Sitesini Gezip Verilerini Alacak Bot Yazmak

Bazı durumlarda projelerinizde bazı sitelerin veri tabanlarına ihtiyacınız olabilir fakat tabiki başka sistemler size veri tabanlarını açmayacaktır.Bugün bu web sitelerinin verilerini ihtiyacımız dahilinde nasıl çekebiliriz bu konu üzerine yoğunlaşacağız.


Başlangıç 
Uygulamamızı C# ile HTMLAgilityPack.dll ini kullanarak yapıyor olacağız.Visual studio üzerinden nuget manager ile HTMLAgilityPack i indirip kullanabileceğimiz gibi isterseniz code plex üzerinden de ilgili dll i indirebilirsiniz.(code plex url :https://htmlagilitypack.codeplex.com/releases/view/90925)

Kısa açıklama
Bu uygulamamız isbnsearch.org sitesindeki kitap bilgilerine ISBN numarası ile ulaşmamızı sağlayacak.
Yani şöyle bir ihtiyacımız olduğunu düşünelim sitemize kitap ekleyeceğiz ama kitap bilgilerini (resim,isim,yayınevi,yazar,vs) tek tek girmek istemiyoruz.İlgili kitabın ISBN numarasını girip kitabın bilgilerini resmiyle birlikte getirmek istiyoruz.


Hadi kodlayalım :)


Öncelikle Book adında bir class ımız olsun ve sonrasında bu class ın içerisindeki kitap bilgilerini dolduran bir metod yazalım.


Book.cs

public class Book
{
  
  private string ISBN;
  
  private string Name;
  
  private string Publisher;

  private string Author;
  
  private string CoverPhotoURL;
  
  private string PublishProperties;
  }

BookFinder.cs

 
public class BookFinder
{

        public Book GetBookInfoByIsbn(string isbn)
        {
            Book bookInfo = new Book();

            try
            {
                //bu kısımda Verilerini alacağımız HTML Sayfa URL kullanım formatını tanımlıyoruz.
                string isbnURL = string.Format("http://www.isbnsearch.org/isbn/{0}", isbn);
                 //Web sayfasına ISBN parametresi ile talep yollayıp, htmml veriyi indiriyoruz.
                Uri url = new Uri(isbnURL);
                WebClient client = new WebClient();
                string html = client.DownloadString(url);

                //HTMLAgilityPack nesnemizin içerisine indirdiğimiz html i yüklüyoruz.
                HtmlAgilityPack.HtmlDocument dokuman = new HtmlAgilityPack.HtmlDocument();
                dokuman.LoadHtml(html);
                 
                //Veri getireceğimiz alanları tanımlıyoruz
                string publisher = string.Empty;
                string published = string.Empty;
                string author = string.Empty;
                string bookName = string.Empty;
                string bookImg = string.Empty;

                #region Kitap detayları getir

                //sayfa içerisinde <div class='bookInfo'> html ini bulup, p taglarının listesini alıyoruz.Verilerimiz e '<p></p>' tagları içerisinde ulaşacağız.
                List bookInfoParagraphs = dokuman.DocumentNode.SelectNodes("//div[@class='bookinfo']").Descendants().Where(x => x.Name == "p").ToList();

                //P tagları içerisinden linq fonksiyonu yardımı ile içerisinde publisher geçen '<p>' tagını getiriyoruz.
                HtmlNode publisherNode = bookInfoParagraphs.FirstOrDefault(h => h.InnerText.Contains("Publisher: "));
                if (publisherNode != null)
                {//veri içerisinden 'Publisher: ' metnini çıkardığımızda elimizde publisher verisi olmuş oluyor.
                    publisher = publisherNode.InnerText.Replace("Publisher: ", "");
                }

                HtmlNode publishedNode = bookInfoParagraphs.FirstOrDefault(h => h.InnerText.Contains("Published: "));
                if (publishedNode != null)
                {
                    published = publishedNode.InnerText.Replace("Published: ", "");
                }

                HtmlNode authorNode = bookInfoParagraphs.FirstOrDefault(h => h.InnerText.Contains("Author: "));
                if (authorNode != null)
                {
                    author = authorNode.InnerText.Replace("Author: ", "");
                }

                HtmlNode bookNameNode = dokuman.DocumentNode.SelectNodes("//div[@class='bookinfo']").Descendants().FirstOrDefault(x => x.Name == "h2");
                if (bookNameNode != null)
                {
                    bookName = bookNameNode.InnerText;
                }

                HtmlNode coverImageNode = dokuman.DocumentNode.SelectNodes("//div[@class='thumbnail']").Descendants().FirstOrDefault(x => x.Name == "img");
                if (coverImageNode != null)
                {
                    bookImg = coverImageNode.GetAttributeValue("src", "");
                }
                if (bookImg.IsEmpty() || bookName.IsEmpty() || author.IsEmpty() || published.IsEmpty() || publisher.IsEmpty())
                {
                    throw new NullReferenceException("Kitap bilgileri bulunamadı!");
                }

                bookInfo.Name = bookName;
                bookInfo.Publisher = publisher;
                bookInfo.CoverPhotoFilePath = bookImg;
                bookInfo.PublishProperties = published;
                bookInfo.Author = author;
            }
            catch (NullReferenceException nullEx)
            {
                bookInfo = null;
            }
            catch (Exception ex)
            {
                bookInfo = null;
            }
                #endregion

            return bookInfo;

        }//End Method

}





Neler Yaptık ? 
 - Verilerine ihtiyacımız olan bir web sayfasına parametre gönderdik ve istediğimiz verileri html olarak aldık.(örnek olarak http://www.isbnsearch.org/isbn/9752103707 linkini inceleyerek kitap verilerinin geldiğini görebilirsiniz)
 - İlgili sayfamızın html ini indirdik ve HTMLAgilityPack i kullanarak html içerisinde gezip ihtiyacımız olan verilerin bulunduğu html taglarından verileri çektik.
 - Herşey hazır :) artık isbn verip istediğimiz kitabın verilerini alabiliriz.


Şimdi artık herhangi bir sitenin verilerine ihtiyacınız olduğunda bu kod da birkaç düzenleme yaparak istediğiniz web sayfasındaki verilere ulaşabilir, kendinize farklı sitelerin içeriklerinden oluşan ve sürekli güncellenen bir veri tabanı hazırlayabilir projelerinizde kullanabilirsiniz :)




Bu blogdaki popüler yayınlar

Cannot resolve the collation conflict between "Turkish_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation.

iki ayrı veri tabanı içindeki tablolar ile işlem yapılmak istendiğinde eğer dil sorunu çıkıyor ise sorgumuzun sonuna 'COLLATE TURKISH_CI_AS' sözcüğünü ekleyerek sorunu çözebiliriz.Örnek : SELECT * FROM veritabani1.dbo.URUN u1 INNER JOIN veritabani2.dbo.URUNLER u2 ON u1.kod = u2.kod COLLATE TURKISH_CI_AS umarım faydalı olmuştur.

SQL DATEADD() Fonksiyonu(Sql de tarihe ay,gün,yıl ekleme)

Kullanım Kalıbı : DATEADD (datepart , number , date ) . datepart ksımına month,year,day vs artırmak istediğimiz tarih birimini yazıyoruz. . number ksımına arttırmak istediğimiz miktarı yazıyoruz. . date kısmına da hangi tarih e ekleneceğini belirtiyoruz. Örnek olarak şu an ki tarihten 1 ay sonrasını görmek için : Şu anki tarih '10-1-2011' olsun(gün,ay,yıl) Sorgu : SELECT DATEADD(MONTH,+1,GETDATE()) Çıktı alacağımız tarih : '10-2-2011' şekinde olacaktır.

Microsoft SQL Server, Error: 18456

sql server da authentication sorunu. genelde sql server kurulumundan sonra sql serverda bir kullanıcı açıldığında şifre ve kullanıcı adı girmenize rağmen girişi kabul etmez. bu durumda önce kullanıcınızın properties status kısmından enabled olup olmadığına bakın. eğer bu enable ise sql server sunucu üzerinde sağ tuş yapıp properties 'den Security sekmesinden "Sql Server And Windows Authentication Mode" seçilmeli ve ardından sql server servisleri yeniden başlatılmalıdır değişikliklerin kayıt edilmesi için. işte sql server artık hem windows authentication ile hemde sql authentication ile çalışabilir artık. Umarım faydalı olur.