Node.js - Cheerio ile Web Scraping/Crawling

2022-01-24

Regex ile Web Scraping makalesinin devamı niteliğindeki bu yazımızda aynı projeyi bu kez cheerio modülünü kullanarak nasıl yapacağımızı anlatmaya çalışacağım. Cheerio modülü, Node.js içinde jQuery metotlarını kullanmamızı sağlayan bir modüldür. Böylece sanki tarayıcıdaymış gibi kod geliştirerek verileri ayıklayabiliriz.

Veri Çekme

Veri çekme adımlarını Regex ile Web Scraping makalesinden inceleyebilirsiniz. Direkt kodu ekleyelim:

const request = require("request-promise");
 
getExchangeInfo();
 
async function getExchangeInfo() {
    let body = await request({
        url: "https://www.qnbfinansbank.enpara.com/hesaplar/doviz-ve-altin-kurlari",
        method: "GET"
    });
    console.log(body);
}

Cheerio ile Web Scraping

Cheerio modülü bize jQuery metotlarını Node.js içinde kullanma imkanı verdiği için, veri ayıklama geliştirmesine başlamadan önce Chrome Developer Tools kullanarak direkt tarayıcı üzerinde jQuery ile istediğimiz verileri ayıklayabiliriz. Haydi başlayalım.

İlk işimiz veri kazıyacağımız adresi tarayıcıdan açıp ardından Dev Tools’u açalım. Dev Tools’u açmanın birçok yolu var. İlki web sayfasında sağ tıklayıp Öğeyi İncele(Inspect) seçeneğini seçmektir. Ya da Mac için Cmd+Option+i, Windows için F12 klavye kısayollarıyla da açabiliriz.

_config.yml

Ardından Dev Tools’un sol üst köşesindeki Inspect iconuna tıklayıp web sitesinden ayıklamak istediğimiz alanın üzerine mouse imlecini getirip HTML’de ilgili alana gidelim.

_config.yml

Bu işlemle birlikte USD, EUR ve Altın alanlarına erişmek için erişmemiz gereken sınıf(lar)ı görebildik.

  • enpara-gold-exchange-rates__table sınıfıyla tanımlanmış bir div altında
  • enpara-gold-exchange-rates__table-item sınıfına sahip elemanlar
  • Bu elemanların altında da span etiketleriyle ayrılmış ve bizim sahip olmak istediğimiz değerler.

Şimdi bu alandaki verileri çekmek için jQuery yazmaya başlayabiliriz. Dev Tools üzerinden Console tab’ına tıkladığımızda bu web sitesi üzerinde çalışacak javascript kodu yazabileceğimiz alan açılır.

_config.yml

İlk olarak jQuery kullanarak bulduğumuz kapsayıcı sınıfın alt elemanlarını çekelim.

$(".enpara-gold-exchange-rates__table").find(".enpara-gold-exchange-rates__table-item");

Ardından bu elemanlar üzerinde dönerek içlerindeki span etiketlerinin verilerine erişebiliriz.

$(".enpara-gold-exchange-rates__table").find(".enpara-gold-exchange-rates__table-item").each((index, item) => {
    console.log($(item).find("span").text());
});

_config.yml

Son olarak bu değerleri bir çıktı olarak istediğimiz objeye yazalım.

let json = {
    usd: {},
    eur: {},
    gold: {}
}
$(".enpara-gold-exchange-rates__table").find(".enpara-gold-exchange-rates__table-item").each((index, item) => {
    let currency = $($(item).find("span")[0]).text();
    let buy = $($(item).find("span")[1]).text();
    let sell = $($(item).find("span")[2]).text();
console.log(currency, buy, sell);
    if (currency.includes("USD ($)")) {
        json.usd.buy = buy;
        json.usd.sell = sell;
    } else if (currency.includes("EUR (€)")) {
        json.eur.buy = buy;
        json.eur.sell = sell;
    } else if (currency.includes("Altın")) {
        json.gold.buy = buy;
        json.gold.sell = sell;
    }
});
console.log(json);

Çıktı olarak elde ettiğimiz sonuç:

_config.yml

Son olarak çıktımızı tam olarak elde edebilmek için değerleri döngü içinde sayısal hale getirelim.

_config.yml

Tüm işimizi tarayıcı üzerinde bitirdik. Şimdi bu kodları Node.js üzerinde gerçekleştirelim. İlk olarak cheerio modülünü kuralım.

npm i cheerio

Ardından cheerio modülünü uygulamaya import edip kullanmaya başlayalım. Request-promise modülü ile web sitesinden aldığımız HTML verisini cheerio modülü ile işlenebilir hale getiriyoruz.

const request = require("request-promise");
const cheerio = require("cheerio");

async function getExchangeInfo() {
    let body = await request({
        url: "https://www.qnbfinansbank.enpara.com/hesaplar/doviz-ve-altin-kurlari",
        method: "GET"
    });
    let $ = cheerio.load(body);
}

Son olarak extractWithCheerio adında bir fonksiyon oluşturup, tarayıcıda yazdığımız kodları oluşturup içine ekleyelim.

function extractWithCheerio($) {
    let json = {
        usd: {},
        eur: {},
        gold: {}
    }
    $(".enpara-gold-exchange-rates__table").find(".enpara-gold-exchange-rates__table-item").each((index, item) => {
        let currency = $($(item).find("span")[0]).text();
        let buy = parseFloat(parseFloat($($(item).find("span")[1]).text().replace(",", ".")).toFixed(3));
        let sell = parseFloat(parseFloat($($(item).find("span")[2]).text().replace(",", ".")).toFixed(3));
        if (currency.includes("USD ($)")) {
            json.usd.buy = buy;
            json.usd.sell = sell;
        } else if (currency.includes("EUR (€)")) {
            json.eur.buy = buy;
            json.eur.sell = sell;
        } else if (currency.includes("Altın")) {
            json.gold.buy = buy;
            json.gold.sell = sell;
        }
    });
   return json
}

Kodun son hali aşağıdaki gibi olacaktır.

const request = require("request-promise");
const cheerio = require("cheerio");

try {
    getExchangeInfo();
} catch (err) {
    console.error("ERR", err);
}

async function getExchangeInfo() {
    let body = await request({
        url: "https://www.qnbfinansbank.enpara.com/hesaplar/doviz-ve-altin-kurlari",
        method: "GET"
    });
    let $ = cheerio.load(body);
    let result = extractWithCheerio($);
    console.log(result);
}

function extractWithCheerio($) {
    let json = {
        usd: {},
        eur: {},
        gold: {}
    }
    $(".enpara-gold-exchange-rates__table").find(".enpara-gold-exchange-rates__table-item").each((index, item) => {
        let currency = $($(item).find("span")[0]).text();
        let buy = parseFloat(parseFloat($($(item).find("span")[1]).text().replace(",", ".")).toFixed(3));
        let sell = parseFloat(parseFloat($($(item).find("span")[2]).text().replace(",", ".")).toFixed(3));
        if (currency.includes("USD ($)")) {
            json.usd.buy = buy;
            json.usd.sell = sell;
        } else if (currency.includes("EUR (€)")) {
            json.eur.buy = buy;
            json.eur.sell = sell;
        } else if (currency.includes("Altın")) {
            json.gold.buy = buy;
            json.gold.sell = sell;
        }
    });
   return json
}

Çıktıyı da görelim:

_config.yml

Cheerio ile web scraping yazımızın sonuna geldik. Umarım faydalı bir içerik olmuştur. İyi çalışmalar.