Node.js ile site içeriklerini kazımak 🐝
--
Bir websitesini kazımanın çeşitli legal, illegal sebepleri olabiliyor. Kimisi gerçekten içeriğini kopyalayıp benzeri siteler yapmak için, kimisi yenilikleri takip edebilmek için çeşitli siteleri kazıyıp kendine bir feed oluşturmak için, kimisi sevdiği şirketin iş ilanlarını kaçırmamak için bla bla bla… :)
Bu görseli özellikle seçtim çünkü veri toplama işini doğru kurgularsanız her çiçekten topladığınız polenlerle kendi balınızı oluşturabilirsiniz. 🍯
Neler yapacağız?
Yapacağımız işlem aslında oldukça basit. Bir web sayfasına istekte bulunacağız. O istek sonucunda bize sayfanın outputu dönecek. Biz de o output içerisinden dilediğimiz elemanları seçip işleyeceğiz.
Bunları yaparken de iki araç kullanacağız. Birisi http istekleri için axios diğeri ise bu istek sonrasında gelen DOM’da gezinebilmek için ihtiyacımız olacak olan jsdom
Hadi Başlayalım
Öncelikle kendimize bir klasör oluşturuyoruz
mkdir nodescrap && cd nodescrap
sonrasında teferruatlarıyla uğraşmamak ve hızlı kurmak adına npm ilişkilendirmesini şu şekilde yapıyoruz:
npm init -y
Buradaki -y komutunu şu şekilde açıklayabilirim. Normalde bu init işlemini
npm init
komutu ile yaparız ve bize o sırada çeşitli sorular sorar, projenin ismi, versiyonu vs vs. -y
kullandığımız noktada ise bu soruları sormadan default değerleri alarak kurulumu gerçekleştiriyor. Hemen sonrasında ise ihtiyacımız olan diğer paketleri yüklüyoruz :
npm i axios jsdom
Böylelikle şöyle bir package.json dosyasımız oluyor :
{ "name": "nodescrap", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "axios": "^0.18.0", "jsdom": "^13.1.0" }}
Bundan sonra yine terminal üzerinden kendimize bir index.js dosyası oluşturuyoruz :
touch index.js
Artık editörümüze geçebiliriz.
Ben bu örnekte hurriyet.com.tr’nin manşet üzerindeki 4'lü haber alanını çekmek istiyorum. O çekeceğim haberleri belki de ufak bir arayüzle kendi local sayfamda göstereceğim. Bu sebeple tanımlamayı o şekilde yapacağım.
const axios = require('axios'), jsdom = require('jsdom'), { JSDOM }= jsdom, url = 'https://www.hurriyet.com.tr';
şimdi belirttiğim urle istek atacağım ve sonrasında response’un datasını işlemesi için fonksiyonuma paslayacağım :
axios.get(url) .then (response => { getNodes(response.data); }) .catch(error => { console.error(error); })
Bundan sonrası da o istekten gelen komple sayfayı tıpkı bir döküman gibi işlemek :
const getNodes = html => { const data = [], // Boş bir array oluşturuyoruz dom = new JSDOM(html), // Yeni bir JSDOM instanceı alıyoruz news = dom.window.document.querySelectorAll('.flash-four-widget-css a'); // dom'dan gelen nodelar arasında gezerek o modülün içerisindeki a etiketlerini çekiyorum. news.forEach(item => { // daha sonra bu seçtiğim öğelerde dönüyorum data.push({ // yukarıdaki boş arraye her elemanın title ve href özelliklerini atıyorum title: item.getAttribute('title'), link: item.getAttribute('href') }) }); console.log(data); // Arrayin son halini yazdırıyorum. Burada elinize gelen data ile ne yapacağınız size kalmış :)}
Şimdi dosyamızı çalıştırıyoruz:
node index
Bu noktadan sonra o obje ile dilediğiniz mini uygulamayı gerçekleştirebilirsiniz. Gerisi sizin hayal gücünüze kalmış :)