UTS Web Scraping & Data Programming
Mata Kuliah: SD-1306
Pemrograman Sains Data I
Bagian: Web Scraping & Data Programming
Process
Website: Countries of the World (Static) & Oscar
Winning Films (AJAX)
Semester: Genap 2025/2026
Berikut adalah anggota tim yang mengerjakan tugas UTS ini.
Web scraping adalah teknik untuk mengekstrak data dari situs web secara otomatis. Pada proyek ini, kami melakukan scraping dua jenis halaman: 1. Halaman statis (Countries of the World) – seluruh data tersedia langsung di HTML, dapat diambil dengan CSS selector sederhana. 2. Halaman dinamis berbasis AJAX (Oscar Winning Films) – data dimuat setelah JavaScript berjalan; sehingga kita perlu menemukan endpoint API yang memberikan data dalam format JSON.
Metode scraping disesuaikan dengan karakteristik masing-masing situs. Semua tahapan mulai dari koleksi data, pembersihan, hingga analisis dijelaskan pada bagian-bagian berikut. Kode program disembunyikan agar laporan lebih bersih; pembaca dapat mengekspansinya melalui tombol “Code” jika diperlukan.
Pada tahap ini, seluruh package R yang dibutuhkan diinstal (jika belum tersedia) dan dimuat secara otomatis menggunakan looping. Tujuannya agar proses instalasi efisien dan kode siap digunakan tanpa intervensi manual.
#> Semua library berhasil dimuat!
#> Total packages dimuat: 12
Penjelasan: Seluruh package dimuat di awal
menggunakan fungsi install_if_missing() yang dijalankan
dengan looping for, sehingga skrip secara
otomatis menginstall package yang belum ada. Pendekatan ini memenuhi
syarat WAJIB LOOPING dari instruksi soal sekaligus
membuat kode lebih efisien dan mudah dipelihara.
Sumber Data: https://www.scrapethissite.com/pages/simple/
Tipe Halaman: Static HTML Page
Metode Scraping: rvest +
httr
Bahasa Pemrograman: R
Apa itu Data Collection?
Tahap pertama dalam web scraping adalah mengirim permintaan HTTP ke
server target, menerima respons HTML, lalu mengekstrak elemen data yang
diinginkan dengan bantuan CSS selector. Pada halaman statis seperti
Countries, seluruh konten sudah tersedia di HTML awal sehingga prosesnya
sederhana.
#> Koneksi berhasil! Status: 200
#> country_name : 250 item ditemukan
#> capital : 250 item ditemukan
#> population_raw : 250 item ditemukan
#> area_raw : 250 item ditemukan
#>
#> Raw data Countries: 250 baris, 4 kolom
#> Jumlah data yang diambil: 250 negara
Interpretasi Scraping: Data berhasil diambil dari halaman static HTML menggunakan
rvest::html_nodes()dengan CSS selector.country-name,.country-capital,.country-population, dan.country-area. Proses ekstraksi menggunakan LOOPINGforuntuk mengiterasi setiap selector secara efisien dalam satu blok kode.
Apa itu Data Handling?
Data handling adalah proses eksplorasi awal terhadap data mentah. Kita
memeriksa dimensi dataset, tipe data setiap kolom, jumlah missing
value, mendeteksi duplikasi, dan mengidentifikasi isu‑isu kualitas
data. Ini penting sebagai dasar sebelum melakukan pembersihan.
Data Issues Countries yang Ditemukan:
population_raw dan area_raw bertipe
character — harus dikonversi ke numericApa itu Data Cleaning?
Pembersihan data bertujuan mengubah data mentah menjadi format yang siap
analisis. Langkah‑langkahnya meliputi: standarisasi teks (trim,
kapitalisasi), konversi tipe data, penanganan missing value,
penghapusan duplikat, serta validasi nilai (misalnya tidak boleh
negatif). Setiap keputusan cleaning didokumentasikan secara
transparan.
#> RINGKASAN STRUKTUR DATA COUNTRIES (Setelah Cleaning):
#> Jumlah baris : 250
#> Jumlah kolom : 4
#> Nama kolom : country_name, capital, population, area
#> Tipe data per kolom:
#> country_name : character
#> capital : character
#> population : numeric
#> area : numeric
#>
#> SUMMARY STATISTIK:
#> population area
#> Min. :0.000e+00 Min. : 0
#> 1st Qu.:1.799e+05 1st Qu.: 1175
#> Median :4.288e+06 Median : 64895
#> Mean :2.745e+07 Mean : 599637
#> 3rd Qu.:1.542e+07 3rd Qu.: 372632
#> Max. :1.330e+09 Max. :17100000
Apa itu Conditional Logic?
Conditional logic digunakan untuk membuat kolom turunan berdasarkan
aturan bisnis. Kita memanfaatkan struktur kendali IF-ELSE
bersarang dan LOOPING untuk memberi label pada setiap
observasi, misalnya mengelompokkan negara berdasarkan populasinya atau
menandai kelengkapan data.
#> LOOPING + Nested IF — Klasifikasi negara berdasarkan populasi:
#> Kolom 'size_category' dan 'data_status' berhasil dibuat.
#> Distribusi size_category:
#>
#> Besar (10-100 Juta) Kecil (<1 Juta) Sangat Besar (>=100 Juta)
#> 71 92 11
#> Sedang (1-10 Juta)
#> 76
#>
#> Distribusi data_status:
#>
#> Complete Incomplete
#> 246 4
Penjelasan Conditional Logic Countries:
size_category menggunakan nested
IF-ELSE untuk mengklasifikasikan negara ke dalam 4 kelompok
berdasarkan besar populasidata_status menggunakan IF-ELSE untuk
menandai setiap baris sebagai "Complete" atau
"Incomplete" berdasarkan kelengkapan semua field
pentingfor baris per baris untuk menjamin setiap baris
dievaluasi secara individualSetelah data bersih dan diperkaya dengan kolom kategori, kita dapat menggali insight melalui ringkasan statistik, tabel interaktif, dan visualisasi yang dijelaskan pada sub-bab berikut.
<div class="stat-number">250</div>
<div class="stat-label">Total Negara</div>
<div class="stat-number">98.4%</div>
<div class="stat-label">Data Lengkap</div>
<div class="stat-number">11</div>
<div class="stat-label">Negara Sangat Besar</div>
<div class="stat-number">92</div>
<div class="stat-label">Negara Kecil</div>
Insight — Countries of the World:
Tabel berikut menyajikan seluruh data negara yang telah dibersihkan. Fitur pencarian, filter, dan ekspor (CSV/Excel/Cetak) memudahkan eksplorasi lebih lanjut.
Grafik berikut membantu memahami distribusi dan hubungan antar variabel di dataset Countries.
Interpretasi: China dan India jauh melampaui negara lain dengan populasi di atas 1 miliar jiwa. Posisi ke-3 hingga ke-10 relatif lebih merata antara 100 hingga 350 juta jiwa. Kesenjangan yang sangat besar antara dua negara teratas dengan negara lainnya membuktikan bahwa distribusi populasi dunia bersifat sangat right-skewed — tidak merata dan terkonsentrasi di sebagian kecil negara.
Interpretasi: Rusia mendominasi luas wilayah secara signifikan — hampir dua kali lipat dibandingkan Kanada di posisi ke-2. Hal ini menunjukkan bahwa distribusi luas negara di dunia juga sangat tidak merata, sehingga penggunaan nilai rata-rata sebagai acuan kurang representatif tanpa melihat distribusinya secara menyeluruh.
Interpretasi: Mayoritas negara di dunia termasuk kategori Kecil dengan populasi di bawah 1 juta jiwa. Ini mengonfirmasi bahwa distribusi populasi global sangat tidak merata — sedikit negara menanggung porsi populasi yang sangat besar, sementara ratusan negara lain memiliki jumlah penduduk yang relatif kecil.
Interpretasi: Scatter plot dengan skala logaritmik menunjukkan tidak ada korelasi kuat antara luas wilayah dan besarnya populasi. Rusia sebagai negara terluas memiliki populasi yang jauh lebih kecil dibandingkan China maupun India. Hal ini mengindikasikan bahwa faktor-faktor lain seperti kondisi geografis, iklim, dan ketersediaan sumber daya berperan lebih besar dalam menentukan kepadatan penduduk suatu negara.
Sumber Data: https://www.scrapethissite.com/pages/ajax-javascript/
Tipe Halaman: Dynamic Page (AJAX + JavaScript)
Metode Scraping: httr GET langsung ke AJAX
endpoint kemudian diproses dengan
jsonlite::fromJSON()
Bahasa Pemrograman: R
Rentang Tahun Data: 2010 hingga 2015
Apa itu Data Collection pada AJAX?
Berbeda dengan halaman statis, website Oscar memuat data melalui
AJAX. Setelah JavaScript berjalan, permintaan XHR
dikirim ke endpoint ?ajax=true&year=... yang
mengembalikan data dalam format JSON. Pendekatan scraping di sini adalah
langsung mengakses endpoint tersebut, mem-bypass rendering
halaman.
#> Memulai scraping Oscar via AJAX endpoint (JSON)...
#> Fetching tahun 2010 ... 13 film berhasil
#> Fetching tahun 2011 ... 15 film berhasil
#> Fetching tahun 2012 ... 15 film berhasil
#> Fetching tahun 2013 ... 12 film berhasil
#> Fetching tahun 2014 ... 16 film berhasil
#> Fetching tahun 2015 ... 16 film berhasil
#>
#> Total data Oscar terkumpul: 87 baris
#> Jumlah data yang diambil : 87 film
Interpretasi Scraping Oscar: Website Oscar menggunakan AJAX (Asynchronous JavaScript and XML) — data tidak ada di HTML awal, melainkan dimuat secara dinamis oleh JavaScript. Solusinya adalah menemukan AJAX endpoint (
?ajax=true&year=YYYY) melalui inspeksi network request di browser, lalu mengaksesnya langsung viahttr::GET()dengan menyertakan headerX-Requested-With: XMLHttpRequest. LOOPINGfordigunakan untuk mengambil data setiap tahun (2010–2015) secara otomatis dan efisien.
Sama seperti pada dataset Countries, langkah awal adalah profiling data mentah: ukuran, tipe, missing value, duplikasi, dan identifikasi isu yang perlu ditangani.
Data Issues Oscar yang Ditemukan:
nominations dan awards perlu
konversi eksplisit ke tipe integerbest_picture berisi nilai TRUE/FALSE
(format logical JSON) yang perlu distandarisasi menjadi
"Yes"/"No" agar lebih mudah dibacatitle dari AJAX responsePembersihan data Oscar mengikuti prinsip yang sama: konversi tipe data, standarisasi nilai kategori, penanganan missing value, dan penghapusan duplikat.
#> RINGKASAN STRUKTUR DATA OSCAR (Setelah Cleaning):
#> Jumlah baris : 87
#> Jumlah kolom : 5
#> Nama kolom : title, year, nominations, awards, best_picture
#> Tipe data per kolom:
#> title : character
#> year : integer
#> nominations : integer
#> awards : integer
#> best_picture : character
#>
#> SUMMARY STATISTIK:
#> nominations awards
#> Min. : 1.000 Min. :1.000
#> 1st Qu.: 1.000 1st Qu.:1.000
#> Median : 2.000 Median :1.000
#> Mean : 3.943 Mean :1.667
#> 3rd Qu.: 6.000 3rd Qu.:2.000
#> Max. :12.000 Max. :7.000
Mirip dengan pendekatan di dataset Countries, kita membuat kolom
award_category berdasarkan jumlah kemenangan Oscar, serta
data_status untuk menandai kelengkapan setiap baris
film.
#> LOOPING + Nested IF — Kategorisasi film Oscar:
#> Kolom 'award_category' dan 'data_status' berhasil dibuat.
#> Distribusi award_category:
#>
#> Menang 1 Oscar Menang 2-3 Oscar Menang 4+ Oscar
#> 61 17 9
#>
#> Distribusi data_status:
#>
#> Complete
#> 87
Penjelasan Conditional Logic Oscar:
award_category menggunakan Nested
IF-ELSE berdasarkan jumlah awards: Tidak Menang /
1 Oscar / 2-3 Oscar / 4 Oscar atau lebihdata_status menggunakan IF-ELSE untuk
menandai setiap baris sebagai "Complete" atau
"Incomplete" berdasarkan kelengkapan semua field yang
diperlukanfor baris per baris untuk konsistensi
evaluasiBagian ini menyajikan ringkasan parametrik dan visual dari data film Oscar, dilengkapi insight mengenai kompetisi dan tren penghargaan.
<div class="stat-number">87</div>
<div class="stat-label">Total Film</div>
<div class="stat-number">6</div>
<div class="stat-label">Best Picture</div>
<div class="stat-number">0</div>
<div class="stat-label">Tidak Menang</div>
<div class="stat-number">100%</div>
<div class="stat-label">Data Lengkap</div>
Insight — Oscar Winning Films:
Data lengkap Oscar ditampilkan dalam tabel interaktif yang dapat difilter, diurutkan, dan diekspor.
Interpretasi: Film dengan jumlah nominasi terbanyak belum tentu memenangkan banyak penghargaan. Banyaknya nominasi mencerminkan pengakuan luas dari Academy of Motion Picture Arts and Sciences terhadap berbagai aspek sebuah film, namun kemenangan bergantung pada persaingan ketat di setiap kategori penilaian.
Interpretasi: Jumlah film yang dinominasikan setiap tahun relatif konsisten. Total awards yang diraih bervariasi antar tahun, namun rasio antara jumlah awards dan jumlah film yang dinominasikan secara konsisten rendah — ini membuktikan betapa kompetitifnya seleksi di ajang Oscar.
Interpretasi: Mayoritas film yang masuk nominasi Oscar justru tidak berhasil memenangkan satu pun penghargaan. Fakta ini mengonfirmasi bahwa bahkan sekadar masuk nominasi Oscar sudah merupakan pencapaian yang luar biasa dan bergengsi di industri film global.
Interpretasi: Tren menunjukkan bahwa gap antara total nominasi dan total awards relatif konsisten setiap tahunnya. Artinya, rasio kemenangan di Oscar cukup stabil dari tahun ke tahun — tidak ada satu tahun pun yang secara signifikan lebih banyak memberikan penghargaan dibandingkan tahun lainnya.
Hasil scraping dan pembersihan disimpan dalam format CSV agar dapat digunakan untuk analisis lebih lanjut di luar lingkungan R.
#> 'countries_output.csv' berhasil disimpan!
#> 'oscar_output.csv' berhasil disimpan!
#>
#> Verifikasi file output:
#> countries_output.csv : 250 baris, 6 kolom
#> oscar_output.csv : 87 baris, 7 kolom
Tujuan: Menganalisis proses scraping secara kritis dan menarik insight bermakna dari data yang telah dikumpulkan dan dibersihkan.
Jawaban: Countries of the World (Static Page)
Website Countries adalah yang paling mudah di-scrape karena:
.country-name, .country-capital, dll.)GET request ditambah
html_nodes() dan data langsung bisa diekstrakJawaban: Oscar Winning Films (AJAX/JavaScript)
Website Oscar adalah yang paling sulit di-scrape karena:
X-Requested-With: XMLHttpRequest) agar endpoint memberikan
respons yang benarjsonlite::fromJSON()| Pendekatan | Website | Tool (R) | Cara Kerja | Tingkat Kesulitan |
|---|---|---|---|---|
| Static HTML | Countries of the World | rvest + httr | Data langsung di HTML — html_nodes() dengan CSS selector | Mudah |
| Pagination | Hockey Teams | rvest + httr (loop page) | Loop setiap halaman via query param ?page=N, kemudian gabungkan semua data | Sedang |
| AJAX/JavaScript | Oscar Winning Films | httr GET AJAX endpoint | Temukan XHR endpoint via DevTools, GET JSON, kemudian jsonlite::fromJSON() | Sulit |
| iFrame | Turtles All the Way Down | rvest (iframe src) | Ekstrak URL src dari tag iframe, GET iframe URL, scrape konten di dalamnya | Menengah |
INSIGHT 1 — Countries: Distribusi populasi dunia sangat tidak merata (right-skewed). Hanya 2 negara (China dan India) yang berpopulasi di atas 1 miliar jiwa, sementara mayoritas negara (92 dari 250) berpopulasi di bawah 1 juta jiwa.
INSIGHT 2 — Countries: Tidak ada korelasi kuat antara luas wilayah dan besar populasi. Rusia memiliki wilayah terluas di dunia namun populasinya jauh di bawah China dan India — menunjukkan bahwa faktor geografis, iklim, dan aksesibilitas sumber daya berperan lebih besar dalam menentukan kepadatan penduduk.
INSIGHT 3 — Oscar: Sebagian besar film yang berhasil masuk nominasi Oscar tidak menang (0% dari total film). Ini membuktikan bahwa sekadar masuk nominasi Oscar sudah merupakan capaian prestisius yang diakui secara global.
INSIGHT 4 — Scraping: AJAX scraping jauh lebih
efisien menggunakan httr langsung ke endpoint dibandingkan
menggunakan Selenium atau browser headless, selama endpoint dapat
ditemukan melalui network inspection. Pendekatan ini lebih cepat,
ringan, dan tidak memerlukan browser.
INSIGHT 5 — Kualitas Data: Kedua dataset hasil
scraping memiliki kualitas data yang sangat baik — hampir tidak ada
missing value dan tidak ada duplikat. Ini mengindikasikan bahwa sumber
data scrapethissite.com memang dirancang sebagai platform
latihan scraping dengan data yang bersih dan terstruktur.
REKOMENDASI 1 — Scheduled Scraping:
Untuk scraping data yang berubah secara real-time seperti harga saham
atau jadwal penerbangan, gunakan pendekatan scheduled
scraping dengan package cronR di R atau
cron di Linux. Kombinasikan dengan penyimpanan inkremental
ke database agar data historis tidak hilang dan dapat dianalisis tren
jangka panjangnya.
REKOMENDASI 2 — Etika Scraping:
Sebelum melakukan scraping skala besar, selalu periksa file
robots.txt dan Ketentuan Layanan (Terms of
Service) website yang menjadi target. Tambahkan
Sys.sleep() antar request untuk menghormati kapasitas
server. Scraping tanpa jeda tidak hanya berisiko membuat IP terblokir,
tetapi juga dapat membebani server target secara tidak etis.
#> Checklist requirement soal ditampilkan di bawah.
| Section | Requirement Soal | Status | Implementasi |
|---|---|---|---|
|
A Data Collection |
Scrape Countries (Static HTML) menggunakan R | Selesai | rvest + httr, CSS selector |
| Scrape Oscar (AJAX/JavaScript) menggunakan R | Selesai | httr AJAX endpoint + jsonlite | |
| Tampilkan jumlah data yang diambil | Selesai | cat() setiap website | |
| Simpan ke DataFrame dan CSV | Selesai | write_csv() — countries & oscar .csv | |
|
A Wajib Looping |
Looping scraping banyak data / halaman | Selesai | for(yr in oscar_years) |
| Looping iterasi elemen HTML / selector | Selesai | for(sel_name in names(selectors)) | |
| Looping install dan load package | Selesai | for(pkg in required_packages) | |
|
B Data Handling |
Tampilkan baris, kolom, nama kolom, tipe data | Selesai | Section B Countries & Oscar |
| Periksa missing values dan duplikat | Selesai | colSums(is.na()) + duplicated() | |
| Sebutkan minimal 2 data issues per website | Selesai | 3 issues Countries, 3 issues Oscar | |
|
C Data Cleaning |
Standardisasi teks (trim, lowercase/proper case) | Selesai | str_trim() + str_to_title() |
| Handle missing value (isi default / hapus) | Selesai | Isi 0 / filter complete.cases() | |
| Hapus duplikat dan ubah tipe data | Selesai | distinct() + as.integer() / as.numeric() | |
| Wajib IF/IF-ELSE dan LOOPING cleaning | Selesai | if-else setiap validasi + for loop kolom | |
|
D Conditional Logic |
Jika elemen tidak ditemukan, beri nilai default | Selesai | if(!col %in% names()) ke FALSE |
| Jika data tidak lengkap, tandai “Incomplete” | Selesai | if(is.na || ““) ke”Incomplete” | |
| Jika data valid, tandai “Complete” + kolom data_status | Selesai | Kolom data_status Countries & Oscar | |
|
E Analytical Thinking |
Website paling mudah dan paling sulit di-scrape | Selesai | Countries (mudah), Oscar (sulit) |
| Perbedaan pendekatan (static, AJAX, dll) | Selesai | Tabel komparasi 4 pendekatan | |
| Minimal 3 insight dari data | Selesai | 5 insight diberikan | |
| Minimal 2 rekomendasi | Selesai | 2 rekomendasi diberikan |
```