Saf Python ile Veri Kazıma (Web Scraping)

Standard

Merhaba,

Web üzerinde veri kazıma işlemleri için birçok yöntem bulunmakta. Tabii ki python‘un bu konudaki güçlü çatılarından birisi olan Scrapy bu iş için biçilmiş kaftan konumunda. Ancak işi programlama olmayan, ancak site ya da siteler üzerindeki verileri python ile alabileceğinin bilincinde olan kişi sayısı da günden güne artmakta. Bu da karşımızda, “acaba kapsamlı bir proje değilde basitçe bir site üzerindeki belirli bilgileri çekmek istiyorsak, en az gereksinimle bunu nasıl yapabiliriz?” sorusunu çıkarıyor.

Aslında yakın zamanda yayınlayacağım bir projemin temellerini araştırırken denk geldiğim güzel bir kütüphaneyi kullanarak bu işi yapabileceğimi farketmem, bu makaleyi oluşturmama sebep oldu. Python 3’ün “requests-html” kütüphanesi, bir site üzerindeki xpath ya da CSS desenlerini takip ederek veri elde etmenize imkan tanıyor. Bunun yanında da birçok imkanla beraber sitedeki verileri de indirmenizi mümkün kılıyor.

Temel olarak bu kütüphanenin sundukları şöyle;

  1. İlki ve de en değerlisi, javascript desteğine sahip oluşu.
    Peki “javascript desteği” ne demek?
    Eğer web geliştirmeye dair birkaç proje yaptıysanız(ki yapmadıysanız da çok sorun değil, burada nasıl olduğuna değinip, kafa karışıklığınızı elimden geldiğince gidereceğim), bir web sitesinin temelde 2 aşamada oluşturulduğunu bilirsiniz. Bir web sitesi, 2 parçadan oluşur. Ön yüz(front-end) ve arka yüz(back-end) birleşerek, kullanıcının siteye başarıyla erişmesini sağlarlar. arka yüzde genellikle kayıt, güncelleme, silme gibi, veritabanı gibi işlemler yapılırken, ön yüzde hareketli objelerin çalıştırılması, formların hazırlanması, gösterimi gibi işlemler sağlanır. İlk zamanlarda bir siteye tıkladığınızda, veriler siz siteye erişim isteği gönderdiğinizde hazır edilip ön yüze ilk aşamada aktarılırken, günümüzde, şemalar statik olarak ilk anda getirilirken, diğer işlemler siteye siz istek yaptıktan sonra, sitenin şeması tarayıcınız tarafından yorumlandıktan sonra, saf javascript ya da onun çatılarından(frameworklerinden) birisiyle sağlanıyor. Bu da siz bir site üzerinden veri alacaksanız, istek yaptığınız anda o veri getirilmemişse ve kullandığınız teknoloji javascript desteklemiyorsa bu veriyi alamamanıza sebep oluyordu. Ancak bu modül, javascript’in doğru şekilde çalışıp, istediğiniz veriyi getirmesini sağlıyor.
  2. CSS ve Xpath Seçiciler
    Bir sitedeki veriyi indirmek için yaygın olarak kullanılan metod, sitenin html iskeleti üzerinde birbirini takip eden desenleri tespit edip bu desenleri takip ederek istenilen veriye ulaşmaktır. Bu seçiciler sayesinde site üzerinde verinin bulunduğu kısımları programa anlatıp bu kısımları kaydetmesini sağlıyoruz.
  3. Otomatik Link Takibi
    Bir site üzerinden veri çekmek istediğimiz zaman, aradığımız veri her zaman tek bir sayfa üzerinde değil, bazen birbirini takip eden sayfalar üzerinde bulunabilmektedir. (bknz: sayfalama/pagination). Bu özellik sayesinde, taramaya başladığımız sayfadan itibaren, sayfa içerisindeki bir link üzerinden başka bir sayfaya geçip veri çekme işlemine buradan devam etmemizi sağlayabiliyoruz.
  4. Bağlantı Sağlama ve Cookie Sabitleme
    Site üzerinde bazen login olduktan sonra verilere erişebiliriz. Bu login işlemi ise genellikle arka tarafta anlık üretilen ve bizim cookie’miz üzerinde tutulan bir anahtar sayesinde site tarafından anlaşılmaktadır. Bu özellik sayesinde bu anahtarı sürekli olarak siteye sunarak login olduktan sonra erişilebilir sayfalara ulaşabilmemiz sağlanmaktadır.
  5. İşlevsel Ayrıştırıcılar(Html Parsers)
    Bir siteye programın ulaşmasını sağladıktan sonraki aşama site içerisinde bizim istediğimiz veriyi ayrıştırabilmektir. Bu ayrıştırıcılar sayesinde site üzerinden veriyi olabilecek en temiz şekilde çekip, kaydedebiliriz.

Bu kadar anlatımın ardından ardından elimizi kirletmeye başlayabiliriz.

  1. Kurulum

    pip install requests-html
  2. Örnekler
      1. Bir site üzerindeki tüm linkleri çekmek;
        from requests_html import HTMLSession
        from pprint import pprint
        
        session = HTMLSession()
        
        response = session.get("https://sezerbozkir.com")
        pprint(response.html.links)
      2. CSS Ayrıştırıcı ile istenilen kısma ulaşmak;
        Örnek olarak sitem üzerindeki sol tarafta bulunan “Son Yazılar” kısmındaki başlıklara ulaşmayı sağlayan kod;

        from requests_html import HTMLSession
        from pprint import pprint
        
        session = HTMLSession()
        
        response = session.get("https://sezerbozkir.com")
        texts = response.html.find("#recent-posts-2", first=True).text.split("\n")
        pprint(texts)

        Kod içerisindeki “first” parametresi bu css’e bağlı birden çok class olma durumunda ilkini seçmeyi sağlıyor.

      3. Xpath İle İstenilen Kısma Ulaşma;
        Örnek olarak sitem üzerinde, ilk sayfadaki konu başlıklarını çekmeyi sağlayan kod;

        from requests_html import HTMLSession
        
        session = HTMLSession()
        
        response = session.get("https://sezerbozkir.com")
        finds = response.html.xpath("//h1[@class='entry-title']/a")
        for piece in finds:
            print(piece.text)
      4. Javascript Desteği;
        Render metodunu çalıştırdıktan sonra sayfadaki javascript fonksiyonları çalıştırılıp, sonucunda üretilen sayfa üzerinde işlem yapabiliyorsunuz.

        from requests_html import HTMLSession
        
        session = HTMLSession()
        
        response = session.get("http://sezerbozkir.com")
        response.html.render()
      5. Site html kodu üzerinden çalışmak;
        from requests_html import HTML
        
        source_code = """<a href='https://sezerbozkir.com'>"""
        html = HTML(html=source_code)
        
        print(html.links)

Elbette bu modülün yapabilecekleri bununla sınırlı değil. Daha detaylı bilgi için sitesine buradan ulaşabilirsiniz.

Bu modül Scrapy gibi gelen verileri şematize ederek bir akış sonucu kaydetme işlemleri gibi komplike çalışmalara izin vermese de kısa vadede istenilen sonuçları elde etmemizi sağlıyor.

Bir sonraki yazımda görüşmek üzere…

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir