Saya menulis artikel kecil ini setelah saya melakukan beberapa web scraping sederhana untuk situs yang saya buat, semuanya sangat mendasar.

NB! Beberapa situs web melarang penggunaan scraper, jadi pastikan hal tersebut diperbolehkan sebelum melakukan scraper. Itupun cobalah melakukan ini dengan dampak sesedikit mungkin (menjalankan banyak panggilan http setiap beberapa detik mungkin tidak terlalu bagus, ya?).

Apa itu pengikisan web

Katakanlah, Anda memerlukan info dari beberapa situs, misalnya daftar artikel dengan link dan penulis. Situs lama biasanya tidak memiliki API untuk membantu Anda melakukan tugas ini, jadi Anda dapat melakukannya secara manual dengan menyalin/menempel atau Anda dapat mengotomatiskan prosesnya dengan program. Itu saja — pengikis web.

Apa yang kita butuhkan

Berikut dari uraian di atas, untuk mencapai tujuan kita memerlukan:

  1. dapatkan HTML halaman;
  2. parsing HTML dan kumpulkan data yang kami minati.

Npm dapat memberi kami banyak paket untuk kedua tugas tersebut.

Permintaan adalah paket terkenal untuk permintaan http dan mungkin cocok untuk Anda — jika halaman yang diinginkan memiliki pengkodean yang didukung oleh Node (yaitu utf8, ascii, biner, hex, ucs2, base64). Jika pengkodean tidak didukung, permintaan akan mengembalikan Anda beberapa abracadabra (tentu saja, ini dapat diperbaiki dengan menggunakan paket yang berhubungan dengan pengkodean). Needle adalah paket lain yang bagus untuk panggilan http dan mungkin lebih mudah untuk digunakan jika halaman Anda memiliki pengkodean non-sepele (seperti pengkodean windows-1251 untuk cyrillics).

Cheerio adalah paket yang cukup populer untuk penguraian DOM dan karena paket ini mengimplementasikan subset jQuery inti, maka mudah untuk mulai mengerjakannya. Selain itu, Anda dapat mengurai HTML yang Anda terima dengan ekspresi reguler, namun ini mungkin cukup menantang.

Jadi, siapkan

Karena kami membuat pengikis yang paling sederhana, kami akan berusaha meminimalkan alat kami. Di folder proyek kita hanya perlu membuat satu file — file untuk semua kode kita. Katakanlah, kami beri nama app.js (atau Anda dapat memberinya nama lain).

Lalu mari kita buat package.json untuk dependensi kita. Dengan antarmuka baris perintah Anda (git bash atau apa pun yang Anda gunakan) masuk ke folder proyek dan ketik

npm init

Isi formulir yang tersedia sesuka Anda, satu-satunya hal yang penting di sini adalah mengatur file kami app.js (atau apa pun namanya) sebagai utama.

Lalu mari kita instal dependensi. Jalankan perintah ini:

npm install needle --save
npm install cheerio --save

“Simpan” adalah tanda untuk menyimpan paket yang Anda instal sebagai dependensi di file package.json. Anda dapat membuka file ini dan memeriksanya, seharusnya terlihat seperti ini:

{
  "name"         : "web-scraper",
  "version"      : "0.0.1",
  "description"  : "my web-scraper",
  "main"         : "app.js",
  "author"       : "me",
  "dependencies" : {
    "cheerio"    : "^0.22.0",
    "needle"     : "^1.4.3"
 }

Sekarang penyiapan kita selesai, waktunya membuat kode!

Membutuhkan modul yang dibutuhkan

Mari mulai menulis kode di file app.js kita. Pertama, kita harus memerlukan semua modul yang kita perlukan untuk scraping:

var needle = require('needle');
var cheerio = require('cheerio');

Sekarang kami memiliki akses ke paket unduhan kami. Namun, kami mungkin ingin menuliskan informasi yang tergores ke dalam beberapa file, tidak hanya menampilkannya di konsol. Jadi mari kita memerlukan modul fs Node:

var fs = require('fs');

…dan itu saja.

Mendapatkan HTML

Panggilan http sederhana adalah tugas yang cukup sepele baik untuk permintaan dan jarum. Saya menggunakan jarum di sini, namun dengan permintaan hasilnya cukup mirip.

needle.get(URL, function(err, res){
  if(err) throw err;
  console.log('Status code: ' + res.statusCode);
});

Untuk memeriksa apakah berhasil, ganti URL dengan alamat asli (seperti “”) dan jalankan kode Anda dengan perintah

node app.js

Jika semuanya berjalan baik, Anda akan menerima kode status 200. Jika halaman yang Anda minta tidak ditemukan (untuk memeriksa coba berikan alamat yang tidak valid pada program Anda seperti “welovecarrots.club”) konsol akan mencatat kode status 404. Jika Anda ingin melihat HTML sebenarnya , tambahkan baris ini:

console.log(res.body); //will show all html body

Untuk scraper sederhana kami, kode itu cukup untuk panggilan http. Dalam beberapa kasus, Anda mungkin perlu melakukan panggilan yang lebih rumit dengan header, parameter, opsi tertentu — namun hal tersebut dilakukan jika halaman yang diinginkan memiliki autentikasi, alamat string kueri yang rumit, dll. Dan di sinilah segalanya mungkin menjadi sangat rumit.

Mengurai HTML

Pertama, kita perlu menyimpan HTML yang kita terima ke dalam beberapa variabel. Karena kami menggunakan cheerio, kami akan melakukan hal ini persis seperti yang mereka sarankan:

needle.get(URL, function(err, res){
  if(err) throw err;
  console.log('Status code: ' + res.statusCode);
  
  var $ = cheerio.load(res.body);
  console.log($); //optional - to check html body
}

Sekarang jika kita memuat halaman non-Inggris atau halaman dengan banyak berbagai simbol dan console.log isinya… uh oh, semua hal itu dienkripsi dan kita tidak dapat memahami apa pun dari konsol kita. Hal ini karena secara default cheerio mendekode entitas. Jika kita ingin mengubahnya, kita bisa menambahkan parameter untuk fungsi pemuatan cheerio:

needle.get(URL, function(err, res){
  if(err) throw err;
  console.log('Status code: ' + res.statusCode);
  
  var $ = cheerio.load(res.body, {decodeEntities: false});
  console.log($); //to check html body
}

Bagaimanapun, sekarang kita bisa mulai mengurai HTML kita. Dengan cheerio ini mirip dengan membangun/mengubah elemen dengan jQuery, sekarang kita perlu membedah DOM alih-alih membuatnya. Bagaimanapun kita mulai dengan melihat DOM asli (gunakan alat pengembang apa pun yang Anda inginkan). Kita perlu menemukan cara untuk menargetkan hanya elemen-elemen yang kita minati.

Dalam skenario terbaik, elemen Anda akan memiliki kelas. Maka sangat mudah untuk menangkapnya!

var title = $('.title').text();
console.log(title);

Tapi mungkin Anda memiliki banyak header dan ingin mengulangi semuanya... Itu juga sederhana:

$('h3').each(function(){
  console.log($(this).text());
}

Jika Anda mengurai HTML yang tidak memiliki kelas apa pun untuk membantu Anda, cheerio memiliki banyak fungsi berguna untuk mengatasinya: kids(), Parents(), next (), sebelumnya(), selanjutnyaSampai() dan seterusnya. Jika Anda merasa sulit menargetkan elemen yang diinginkan, pastikan untuk membaca dokumentasi, ini sangat membantu. Ingatlah bahwa text() dan html() cara kerjanya sangat berbeda: text() akan memberi Anda “konten teks dari setiap elemen dalam kumpulan elemen yang cocok” sementara html() memberi Anda “ string konten html dari elemen yang dipilih pertama” .

Keluaran

Selalu menyenangkan untuk melihat hasil program di konsol, tetapi jika kita benar-benar membutuhkan informasi yang tergores, kita biasanya memerlukannya dalam sebuah file — sebagian besar dalam .json, mungkin terkadang dalam .txt. Dengan Node.js, ini adalah tugas yang sederhana. Pertama, kami memerlukan dua modul sederhana dari Node itu sendiri (Anda tidak perlu mengunduhnya melalui npm atau benang).

var fs = require('fs');                       
var util = require('util');

Sekarang, yang kita butuhkan hanyalah sebuah variabel untuk menyimpan data kita. Karena kita sering menginginkannya dalam format json, kita harus membuat struktur json tersebut (membuat semacam "skema") dan kemudian memasukkan data saat kita mengumpulkannya. Dan kemudian simpan ke hard drive dengan satu baris kode:

fs.writeFileSync('./myData.json', util.inspect(JSON.stringify(json)) , 'utf-8');