Ekşi Sözlük kullanıcı entrylerini web scraper ile çekmek

Ekşi sözlük, gündemin hızlı aktığı ve binlerce kullanıcı tarafından yorumlandığı, aynı zamanda niş bir konu hakkında detaylı bilgilerin elde edilebildiği veya o konu hakkında bilgi paylaşımı yapılabilen text tabanlı bir sosyal ağdır. Ekşi Sözlük, popülaritesinin artmasıyla beraber üçüncü parti Ekşi Sözlük uygulamalarını da ortaya çıkardı. Şükela Reader, EkşiCep gibi uygulamaların Ekşi Sözlük resmi uygulamalarının yerini tutmasıyla, Sözlük API gereksinimi günden güne arttı.

Her ne kadar Ekşi Sözlük resmi API hizmeti sunmasa da geliştiriciler bir şekilde eksik veya tam kendi geliştirdikleri çözümleri kendi uygulamalarında kullandı, kullanmaya devam ediyorlar.

Bir kullanıcının tüm entrylerini çekme gereksinimim olmuştu. Hem resmi, hem de diğer API hizmetlerine baktığımda böyle bir fonksiyonun açık biçimde kullanıma hazır olmadığını gördüm. Bu yüzden basit bir scraper yazmak istedim. Bu uygulamada http kütüphanesini kullandım.

İsteği oluşturmak

Öncelikle entrylerini çekeceğimiz kullanıcının URL’ini oluşturalım.

var url = 'https://eksisozluk.com/son-entryleri?nick={burayaNickGelecek}&p={sayfaSayisi}&_={buraya current Epoch gelecek}';

Yukarıda oluşturduğumuz URL’ye şöyle bir gerçek kullanım örneği verebiliriz:

var url = 'https://eksisozluk.com/son-entryleri?nick=vitruvius%20kadini&p=1&_=1617549073157';

Daha sonrasında headers içerisine yazmamız gereken User-Agent, referer ve cookie değişkenlerimiz var. Cookie’yi Ekşiyi ziyaret ederken kullandığınız Cookie ile doldurabilirsiniz.

  var response = await http.get(
    url,
    headers: {
      'authority': 'eksisozluk.com',
      'method': 'GET',
      'path':
          '/son-entryleri?nick=vitruvius%20kadini&p=1&_=${DateTime.now().microsecondsSinceEpoch}',
      'scheme': 'https',
      'accept': '*/*',
      'accept-encoding': 'gzip, deflate, br',
      'accept-language': 'en-US,en;q=0.9',
      'cookie':
          'ASP.NET_SessionId=wuz4wgqcvoun41v2aginrbfx; __RequestVerificationToken=0sHFFmJiIH3yK2t0h4pSdMFRyrpNqWlEeu0Bp3k2lZIHQz2m5aTyHukzCnT6e_FtvWlRp0i1epxRfHsvbWFSdPAR5Fgq1aqv2o-hc8SCLu41; notheme=1; channel-filter-preference-cookie=W3siSWQiOjEsIlByZWYiOnRydWV9LHsiSWQiOjIsIlByZWYiOnRydWV9LHsiSWQiOjExLCJQcmVmIjpmYWxzZX1d; alertsnap=637498013945655300; iq=ff743af321a9483a8abb2a69a3e03823; __cfduid=ddc81298a71e40567f9eced713327ea2a1616999761; a=JISnId4SXiylOiNYxjLhs14tYD7CWTI8m0f01arg173X9qGxSKN6vxSr5qq3MddXML9/BkmRr3UXo/c8jFLo4jzA90EdmzNlHVK85MhjBr70XXdVgeYk34PIh2rmtfyqTp++/MxXkXQU64SdOmHy4/pXEx6/85+1jQ9a7VO7EG3CaxAr4q/kLYWno4SiATDB',
      'referer': 'https://eksisozluk.com/biri/vitruvius-kadini',
      'sec-fetch-dest': 'empty',
      'sec-fetch-mode': 'cors',
      'sec-fetch-site': 'same-origin',
      'sec-gpc': '1',
      'user-agent':
          'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
      'x-requested-with': 'XMLHttpRequest',
    },
  );

html/parser.dart kütüphanesini uygulamamıza eklediysek, dönen sonucu parse edip bir döküman haline getirmemiz gerekiyor.

Dönütü parçalamak

  var document = parse(response.body);

Daha sonrasında da elementleri querySelector ile seçip düzenli hale getirebilirsiniz. Uygulamamda plain text olarak bıraktım çünkü daha sonrasında ihtiyacım olmadı. 🙂

  var ch = document.querySelector('#topic').children;
  ch.forEach((f) {
    print(f.querySelector('#title').text); // Entry başlığı
    print(f.querySelector('#entry-item-list > li > div').text); // Entry içeriği    
print(f.querySelector('#entry-item-list > li > footer > div.info > a.entry-date.permalink')
        .text); // Entry tarihi
    print(f.querySelector('#entry-item-list > li').attributes['data-id']); // Entry Id'si
  });

Her sayfa için sayfa sayısı sayacını url üzerinden arttırıp, değerler null dönene kadar devamlı request atarak bir kullanıcının tüm entrylerini çekebilirsiniz.



Dart ile web scraper oluşturma örneği verdiğim bu yazıda umarım faydalı olabilmişimdir. Bir diğer örneğe bakmak için Dart ve Web Scraper yazımı okuyabilir ve oradaki projeden faydalanabilirsiniz.


Okuyucuya Not

Merhaba okuyucu! Blogum son zamanlarda yüksek trafik almaya başladı ve bu durumdan memnunum fakat aynı zamanda siz ziyaretçileri tatmin edememekten endişeliyim. 🙂 Eğer yazılarım ile ilgili bir tavsiyeniz olursa mail adresimden bana ulaşabilir veya Twitter üzerinden direct message gönderebilirsiniz. Github’ta örnek olarak yaptığım projelere göz atmak isterseniz de bu linki kullanabilirsiniz. Umarım bu ziyaretinizle size bir şeyler katabilmişimdir.

Sağlıcakla kalın!