Sepertinya belum ada kata Bahasa Indonesia yang baku sebagai padanan kata scraping (atau lengkapnya; web scraping). Sederhananya, (web) scraping bisa diartikan sebagai memanen, mengurai atau mengambil data dari suatu situs web.
Jika situsnya milik pribadi tentu tidak menjadi masalah, namun bagaimana jika situsnya milik pihak lain? Di sinilah kejelasan web scraping mulai memudar menjadi abu-abu.
Namun dalam kesempatan kali ini, kita biarkan hal tersebut menjadi kajian para ahli hukum. Saya hanya akan sedikit menuliskan cara bagaimana memanen data dari situs KBBI.
Mengapa mesti mengambil data Kamus Besar Bahasa Iindonesia Daring dengan cara scraping?
Ini bermula dari keisengan mengoprek bot Telegram. Berawal dari niat menambah fungsi kamus Bahasa indonesia dari KBBI, ternyata saya menemukan kendala mendapatkan sumber data yang mudah diakses.
Saya bisa dengan relatif mudah mendapat sumber data untuk bahasa Inggris dari oxforddictionaries.com, atau alat terjemah dari Yandex. Tapi tidak untuk Bahasa Indonesia.
Kini bot Telegram yang saya oprek tersebut telah tewas. Dan didasari keinginan agar pengetahuan dibaliknya tidak ikut menghilang, maka ditulislah artikel ini.
Jika Anda hendak mengikuti cara scraping sesuai yang saya akan tulis di bawah ini, patut diingat bahwasanya saya berlepas diri dari segala yang Anda lakukan.
Mungkin benak Anda bertanya, mengapa NodeJS?
Tidak ada alasan selain karena pengetahuan scraping ini saya peroleh kala membuat bot Telegram yang berdasar NodeJS. Jadi bukan karena alasan keunggulan teknis, kemudahan atau lainnya.
Sesuai judul, kita akan melakukan scraping web kbbi.kemdikbud.go.id untuk mencari arti suatu kata bahasa Indonesia. Proses scraping dilakukan otomatis dengan bantuan pustaka node-scrapy di NodeJS. node-scrapy
ini sendiri merupakan antarmuka yang lebih "manusiawi" untuk pustaka request dan cheerio. Jadi request
yang meminta data, dan cheerio
yang memanen data.
Dan karena cheerio
tidak bisa memanen data dari situs dinamis yang berdasar javascript, begitu pula node-scrapy
. Untuk menguji apakah kita bisa memanen data dari sebuah situs dengan menggunakan cheerio
, coba matikan javascript pada situs tersebut. Jika data yang diinginkan masih tetap tampil walau javascript telah dimatikan, maka kita bisa menggunakan cheerio
untuk memanen data dari situs tersebut.
Dan untungnya kbbi.kemdikbud.go.id masuk dalam kategori scrapable.
Baiklah kita mulai saja.
Memulai
Seperti biasanya tiap kali memulai proyek NodeJS:
- Buat folder untuk proyek. Misalnya nama folder tersebut kbbi.
mkdir kbbi
- Masuk ke dalam folder tersebut.
cd kbbi
Buat berkas
package.json
. Dengan cara:-
Menggunakan
npm init
kemudian memasang paketnode-scrapy
menggunakan perintahnpm i node-scrapy
. -
Menulis berkas
package.json
secara manual kemudian menjalankan perintahnpm install
untuk memasang paket yang diperlukan. Berikut contohpackage.json
-nya:{ "name": "kbbi", "version": "0.0.1", "description": "Mencari arti kata di KBBI Daring", "main": "kbbi.js", "author": "Sahri Riza Umami", "dependencies": { "node-scrapy": "latest" } }
-
Menggunakan
Membuat skrip
Dalam package.json
di atas, saya contohkan main script adalah kbbi.js
. Gunakan penyunting teks andalan Anda untuk membuat dan menyunting berkas kbbi.js
sebagai tempat kita menempatkan skrip scraper.
Sunting skrip kbbi.js
untuk mengisikan baris-baris berikut:
- Muat pustaka
node-scrapy
.const scrapy = require('node-scrapy')
- Buat variabel untuk laman kbbi.
const url = 'https://kbbi.kemdikbud.go.id/entri/'
- Buat variabel untuk kata yang akan kita cari artinya.
const kata = process.argv.slice(2).join(' ')
Rencananya, kita akan mencari arti kata dengan cara mengetik perintah
node kbbi.js <kata_yang_dicari>
.
NodeJS akan mengumpulkan perintah ke dalam array. Misal perintahnode kbbi.js aku
akan disusun menjadi['node', 'kbbi.js', 'aku']
, dengan0 = node
,1 = kbbi.js
dan2 = aku
.
Nah,.slice(2)
akan mengiris bagian depan array dan mengambil mulai dari nilai ketiga (karena NodeJS menghitung mulai dari 0) hingga akhir.
Bagaimana jika kita mencari arti kata yang majemuk? Misal "kaki tangan"? Ini gunanya.join(' ')
. Ia akan menggabungkan kata jamak dan memberi spasi diantaranya. - Situs kbbi.kemdikbud.go.id tidaklah rumit. Namun penampilan arti katanya saya dapati tidaklah teratur. Karenanya kita perlu membuat sebuah model data untuk menampung hasil scraping.
const model = { lema: , arti: }
lema
adalah tempat menampung kata yang kita cari artinya, danarti
adalah penampungan dari arti-arti kata yang berhasil kita scrap. Untuk memberi gambaran awal apa yang akan kita isi di model-model tersebut, silakan lihat contoh-contoh di reponode-scrapy
.node-scrapy
memanen data dengan cara menelusuri DOM dari sebuah halaman web. Karenanya kini kita perlu menyediakan elemen apa saja yang patut dikumpulkan olehnode-scrapy
.
Hampir semua peramban web modern telah memiliki fitur web development, namun di sini saya hanya akan mencontohkan menggunakan Firefox.
Silakan jalankan Firefox dan buka laman https://kbbi.kemdikbud.go.id kemudian ketikkan suatu kata untuk dicari artinya. Misal kita ketik kata "apa". Setelah hasil pencarian muncul, klik kanan pada tulisan "apa" dan pilihInspect Element (Q)
. Hasilnya akan tampak seperti berikut:
Bisa kita lihat lema selalu ditulis dalam tag
<h2>
. Masukkan tag ini ke dalam model data.const model = { lema: 'h2', arti: }
Sekarang telaah elemen pada bagian arti kata. Ternyata kita mendapati dua hasil:
-
Kata "apa" di bagian atas memiliki banyak arti yang disusun menggunakan tag
<ol>
. Jadi elemen untuk arti "apa" di bagian ini adalahol li
, yang artinyanode-scrapy
akan mengambil data tag<ol>
yang memiliki child<li>
.
-
Sementara kata "apa" di bagian bawah hanya memiliki satu arti yang ditulis dalam tag
<ul>
. Namun kita tidak bisa langsung menuliskan elemen ini ke model data karena dalam halaman terdapat banyak tagul > li
. Untungnya, tagul
untuk arti lema memiliki sebuah class bernamaadjusted-par
.
Jadi elemen untuk arti kata "apa" yang kedua ini bisa kita tulis sebagaiul.adjusted-par
, yang artinyanode-scrapy
hanya akan mengambil data pada tagul
jika ia memiliki classadjusted-par
.
Akhirnya, model data selengkapnya kita dapati sebagai berikut:
const model = { lema: 'h2', arti: ['ol li', 'ul.adjusted-par'] }
-
Kata "apa" di bagian atas memiliki banyak arti yang disusun menggunakan tag
- Saatnya untuk membuat logika untuk meminta dan memanen data.
scrapy.scrape(url + encodeURIComponent(kata), model, (err, data) => { if (err) return console.log(err) console.log(data) })
node-scrapy
akan meminta data dariurl + encodeURIComponent(kata)
dan kemudian memanen data berdasarmodel
. Hasil scrap akan disimpan dalamdata
dan jika ternyata mendapati galat akan disampaikan dalamerr
.
Barisif (err) return console.log(err)
berarti jika skrip mendapati galat, hentikan skrip dan tampilkan error.
Sementara barisconsole.log(data)
artinya jika proses lancar, tampilkan data hasil scraping ke konsol.
Tampilan skrip kbbi.js
selengkapnya adalah seperti berikut:
const scrapy = require('node-scrapy') const url = 'https://kbbi.kemdikbud.go.id/entri/' const kata = process.argv.slice(2).join(' ') const model = { lema: 'h2', arti: ['ol li', 'ul.adjusted-par'] } scrapy.scrape(url + encodeURIComponent(kata), model, (err, data) => { if (err) return console.log(err) console.log(data) })
Menjalankan skrip
Untuk menjalankan skrip, gunakan pola perintah berikut: node kbbi.js KATA-YANG-AKAN-DICARI-ARTINYA
.
Misal untuk mencari arti kata "apa":
$ node kbbi.js apa { lema: [ 'apa1', 'apa2' ], arti: { '0': [ 'pron kata tanya untuk menanyakan nama (jenis, sifat) sesuatu: ular -- ini?; pohon -- yang kautanam?', 'pron kata tanya untuk pengganti sesuatu: -- yang dimaksudkan orang itu tadi?', 'pron kata tanya untuk menanyakan pertalian kekeluargaan: (pernah) --mu anak itu?', 'pron pengganti sesuatu yang kurang terang; pengganti barang sesuatu: ia tidak tahu -- isi kotak itu', 'p hor untuk menghaluskan permintaan: sudi --lah kiranya Bapak mengabulkan permohonan kami', 'p cak untuk mendahului kalimat tanya: -- besok ada ulangan? -- tamu itu pamanmu?', 'p cak atau: mau minum teh -- kopi; jadi berangkat hari ini -- besok' ], '1': 'n Mdr buah tanaman sirih' } }
Atau mencari arti "kaki tangan":
$ node kbbi.js kaki tangan { lema: 'kaki1 » kaki tangan', arti: { '0': [ 'kaki dan tangan', 'ki orang yang diperalat orang lain untuk membantu' ], '1': null } }
Keluaran skrip ini memang belum sepenuhnya "manusiawi" namun pastinya telah mudah untuk dicerna. Kini kembali ke kreativitas kita untuk mengolah data ini menjadi bentuk yang diinginkan.
Demikian bagaimana menggunakan pustaka node-scrapy
di NodeJS untuk scraping laman web kbbi.kemdikbud.go.id guna mencari arti kata Bahasa Indonesia.
Kesulitan yang saya rasakan dalam melakukan scraping seperti di atas adalah bagaimana menelusuri DOM dan menemukan elemen yang tepat untuk data yang diinginkan. Namun itu pastinya karena saya bukanlah web developer, bagi Anda yang berpengetahuan di bidang ini pastilah tidak akan merasakan kerumitan yang sama.
Akhir kata, happy scraping dan bijaklah dalam melakukannya.
Semoga bermanfaat.
"Dan karena cheerio tidak bisa memanen data dari situs dinamis yang berdasar javascript, begitu pula node-scrapy."
BalasHapusKalimat tersebut aneh strukturnya
Wah, kumaha atuh?
HapusMaksudnya, karena node-scrapy itu basisnya make cheerio, jadi jika cheerio ga bisa scraping web dinamis yang penuh javascript, maka node-scrapy juga ga bakalan bisa.
Barangkali "Dan karena" bisa dihilangkan saja.
HapusHmmm... Ane biarkan dulu lah :D
HapusAnggap saja sebagai ciri khas
Hatur nuhun
BalasHapusSami-sami
HapusParsing arraynya gimana min?
BalasHapusNah, ini kembali ke kreativitas ente :D
HapusKarena artikelnya fokus di scraping, saya hentikan bahasan sampai scraping saja.
Kalaupun datanya ingin diolah lebih lanjut, kan bentuknya masih berupa array, jadi saya rasa masih mudah untuk diolah lebih lanjut.