21 Haziran 2015 Pazar

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 :)




Yunus Emre Web Developer

Morbi aliquam fringilla nisl. Pellentesque eleifend condimentum tellus, vel vulputate tortor malesuada sit amet. Aliquam vel vestibulum metus. Aenean ut mi aucto.