Contoh Web Scraping dengan Python

6058

Materi di penghujung pertemuan semester ini bukan tugas/latihan ya. Tulisan ini bermaksud untuk memberikan pencerahan kepada kalian tentang bagaimana mudah (atau sulitnya) proses web scraping menggunakan Python. Adapun website yang akan kita coba scrap adalah news section Studentsite Gunadarma.

Library yang digunakan ada dua: requests dan BeautifulSoup

Install keduanya sekaligus dengan cara

pip install requests beautifulsoup4

nanti outputnya di shell kalian seperti ini:

Installing collected packages: soupsieve, beautifulsoup4
Successfully installed beautifulsoup4-4.9.3 soupsieve-2.2.1

Query Situs Web dengan requests

Coba cek apakah kita bisa mengakses website SS UG via script Python:

import requests

# URL Studentsite UG
url_ss = 'https://studentsite.gunadarma.ac.id/'

laman_ss = requests.get(url_ss)
# jika sukses, maka status query ini adalah 200, alias OK
print(f'Status GET laman SS UG: {laman_ss.status_code}')

Output yang diharapkan:

Status GET laman SS UG: 200

Jika 200, mari kita lihat struktur laman (dalam HTML):

# cetak HTML
print(laman_ss.content)

Outputnya akan terlihat seperti di bawah. Tidak terlalu nyaman dipandang. Baik kode HTMLnya apalagi situsnya 😏

b'<!DOCTYPE html> \n<html lang="en">\n<head> \n\n    <meta charset="UTF-8">\n<!--[if IE]><meta http-equiv=\'X-UA-Compatible\' content=\'IE=edge,chrome=1\'><![endif]-->\n<title>Universitas Gunadarma...

Ok harusnya so far so good

Menggunakan BeautifulSoup4 untuk Parsing

Nama lib-nya saya singkat BS4 ya. Susah nulisnya. Kita coba ubah output HTML di atas menjadi 0.000001% lebih baik lagi dengan cara parse dengan BS4 lalu panggil metode prettify().

from bs4 import BeautifulSoup  # ini sebaiknya ditaruh di bagian atas file
soup = BeautifulSoup(laman_ss.content, 'html.parser')
print(soup.prettify())

Hasil dari print() (saya truncate ya..):

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8"/>
  <!--[if IE]><meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'><![endif]-->
  <title>
   Universitas Gunadarma - StudentSite :: UG SS
  </title>

Ok. Sekarang paling tidak sudah tidak terlalu beracun bagi mata.

Cari elemen HTML <h2> dengan nilai teks "Berita Terkini". Amati kode HTML di bawahnya, kita akan melihat bahwa mereka menggunakan <div> dengan nama kelas .col-sm-12 > content-box sebagai kontainer elemen berita.

Setiap elemen item berita terdiri atas judul, ringkasan isi (maksudnya isi berita yang di-truncate), dan link 'Lihat Selengkapnya'. Begitulah kurang lebihnya saya mohon maaf.

Kita akan mencetak mereka ke layar, lalu simpan ke file teks. Tentu saja, memanfaatkan lib lain, kalian bisa juga save ke excel, misalnya dengan lib openpyxl. Tapi layar dulu aja..

Query semua elemen dengan nama kelas .content-box:

# ambil semua elemen tertentu ke dalam list
kontainer_berita = soup.find_all('div', class_='content-box')
print(kontainer_berita)

Sekarang semua <div class="content-box"> sudah masuk ke dalam list kontainer_berita berkat metode find_all(). Kita tinggal iterasi satu per satu untuk menemukan judul dan teks rangkuman.

Catatan: find_all() menerima dua parameter: tag HTML dan nama kelasnya, jika ada. Sedangkan get_text() mengambil inner text dari elemen dan dari semua elemen di dalam elemen itu.

# siapkan dua list kosong untuk menampung judul dan rangkuman
judul_list = []
ringkasan_list = []

for berita in kontainer_berita:
    for judul in berita.find_all('h3'):
        judul_string = judul.get_text()
        # buang spasi yang tidak diperlukan
        judul_rapi = ' '.join(str(judul_string).strip().split()) 
        print(judul_rapi)
        # append judul ke list
        judul_list.append(judul_rapi)

    for rangkuman in berita.find_all('div', class_='content-box-wrapper'):
        rangkuman_rapi = ' '.join(str(rangkuman.get_text()).strip().split())
        print(rangkuman_rapi)
        # append teks rangkuman ke list
        ringkasan_list.append(rangkuman_rapi)

Untuk menghapus spasi dan whitespace yang berlebihan, kita harus menggunakan trik khusus sebagaimana terlihat di judul_rapi dan rangkuman_rapi. Sekarang list judul_list dan ringkasan_list sudah terisi.

Output:

[TERBARU] PENDAFTARAN WORKSHOP DIGITAL JOURNALISM: CREATE NEWS WITH SOCIAL ANALYSIS & DATA JOURNALISM
Fakultas Ilmu Komunikasi Universitas Gunadarma menyelenggarakan online workshop dengan tema "Digital Journalism: Create News with Social Network Analysis & Data Journalism". Pelaksanaan online workshop pada: Hari/Tanggal: Rabu, 23 Juni 2021 Pukul: 08.00-16.00 WIB Melalui Zoom Cloud Meeting Pembicara: 1. Ahmad Fatoni, S.I.Kom., MM (Dosen Ilmu Komunikasi Universitas Gunadarma) 2. Made Anthony Iswara (Peneliti di Tirto.ID) Selengkapnya Diposting oleh : Admin pada 2021-06-14 12:18:39

Jika sudah sampai disini, sekalian simpan ke file text:

with open('berita.txt', mode='w') as berita_file:
    for judul, rangkuman in zip(judul_list, ringkasan_list):
        berita_file.write(judul)
        berita_file.write('\n')
        berita_file.write(rangkuman)
        berita_file.write('\n\n')

Naah, teks yang dihasilkan akan memuat judul dan ringkasan, dipisahkan dengan baris kosong (\n\n).

[TERBARU] PENDAFTARAN WORKSHOP DIGITAL JOURNALISM: CREATE NEWS WITH SOCIAL ANALYSIS & DATA JOURNALISM
Fakultas Ilmu Komunikasi Universitas Gunadarma menyelenggarakan online workshop dengan tema "Digital Journalism: Create News with Social Network Analysis & Data Journalism". Pelaksanaan online workshop pada: Hari/Tanggal: Rabu, 23 Juni 2021 Pukul: 08.00-16.00 WIB Melalui Zoom Cloud Meeting Pembicara: 1. Ahmad Fatoni, S.I.Kom., MM (Dosen Ilmu Komunikasi Universitas Gunadarma) 2. Made Anthony Iswara (Peneliti di Tirto.ID) Selengkapnya Diposting oleh : Admin pada 2021-06-14 12:18:39

[TERBARU] Pertemuan Mahasiswa Sistem Informasi Angkatan 2014, 2015 dan 2016
Sehubungan dengan akan berakhirnya perkuliahan semester ATA 2020/2021, kami dari Program Studi Sistem Informasi bermaksud mengadakan kegiatan pertemuan mahasiswa/i Sistem Informasi angkatan 2014, 2015 dan 2016 yang belum menyelesaikan studi. Pertemuan ini bertujuan untuk memberikan pengarahan dan konseling dalam penyelesaian masa studi. Untuk itu, kami mengharapkan kehadiran mahasiswa/i angkatan 2014, 2015 dan 2016 yang belum menyelesaikan studi pada kegiatan tersebut yang insya Allah akan diselenggarakan pada : Selengkapnya Diposting oleh : Admin pada 2021-06-04 09:48:42

...

There you go.

Kode Lengkap

import requests

# URL Studentsite UG
url_ss = 'https://studentsite.gunadarma.ac.id/'

laman_ss = requests.get(url_ss)
# jika sukses, maka status query ini adalah 200, alias OK
#print(f'Status GET laman SS UG: {laman_ss.status_code}')

# cetak HTML
#print(laman_ss.content)

from bs4 import BeautifulSoup  # ini sebaiknya ditaruh di bagian atas file
soup = BeautifulSoup(laman_ss.content, 'html.parser')
# print(soup.prettify())

# ambil semua elemen tertentu ke dalam list
kontainer_berita = soup.find_all('div', class_='content-box')
#print(kontainer_berita)

# siapkan dua list kosong untuk menampung judul dan rangkuman
judul_list = []
ringkasan_list = []

for berita in kontainer_berita:
    for judul in berita.find_all('h3'):
        judul_string = judul.get_text()
        # buang spasi yang tidak diperlukan
        judul_rapi = ' '.join(str(judul_string).strip().split()) 
        print(judul_rapi)
        # append judul ke list
        judul_list.append(judul_rapi)

    for rangkuman in berita.find_all('div', class_='content-box-wrapper'):
        rangkuman_rapi = ' '.join(str(rangkuman.get_text()).strip().split())
        print(rangkuman_rapi)
        # append teks rangkuman ke list
        ringkasan_list.append(rangkuman_rapi)

with open('berita.txt', mode='w') as berita_file:
    for judul, rangkuman in zip(judul_list, ringkasan_list):
        berita_file.write(judul)
        berita_file.write('\n')
        berita_file.write(rangkuman)
        berita_file.write('\n\n')