Belajar python: Scraping situs


BAIKLAH, sebelum ayam berkokok, rencana menulis 2 postingan di hari ini harus segera selesai. Tadinya mau nulis tentang mudik, tapi sadar saya orang udik yang tak pernah mudik, jadi ngapain nulis tentang mudik? Karena itu mari belajar bahasa Slytherin saja.

Kenapa harus python? Entahlah, sejak beberapa tahun lalu saya sangat suka dengan bahasa ini. Suka bukan berarti berkorelasi dengan paham ya. Karena faktanya, kemampuan saya menulis kode di python ya masih setingkat newbie :D.

Salah satu alasan saya suka python adalah bejibunnya librari yang mudah digunakan. Tinggal install lewat pip, voila, sudah bisa langsung dipakai. Jadi bagi pra-newbie seperti saya, librari yang segunung itu sangat membantu ketika iseng mau bikin sesuatu.

Seperti keisengan kali ini. Judulnya sih mungkin agak wah gitu, padahal kalau pakai python dan librarinya, membaca halaman web alias web scraping (entah bahasa Indonesianya apa) itu cukup mudah. Setidaknya kodenya nggak banyak-banyak amat.

Eh web scraping itu apa? Sederhananya ya itu, ‘membaca’ halaman web dan mengekstrak isinya sesuai kepentingan si pembuat.

Misalnya saya ingin mengambil setiap berita di laman kompas.com dan mengolahnya lebih lanjut. Kalau secara manual, langkahnya mungkin seperti ini:

1. Buka halaman indeks kompas.com
2. buka satu per satu beritanya
3. salin-rekat alias copy paste judul dan isi beritanya
4. Ulangi langkahnya sampai semua berita disalin.
5. Kemudian capek

Nah untuk web scraping dengan python, librari yang bisa dipakai adalah BeautifulSoup versi 4 alias bs4. Dengan bs4, kita dapat dengan mudah mengolah data html mentah untuk diekstrak isinya. Caranya? Ya analog dengan empat langkah di atas. Bedanya, kali ini dijalankan otomatis.

Jadi, setidaknya ada dua fungsi yang harus ada, yaitu fungsi yang mengekstrak halaman indeks dan fungsi yang mengekstrak setiap halaman berita. Sebenarnya satu fungsi juga cukup, tapi ya gitu, bacanya malah pusing.

Oke, mari kita buat fungsi-fungsinya. Fungsi pertama adalah mengekstrak setiap tautan di halaman indeks kompas.com dan nanti hasilnya disimpan di berkas link-tanggal.txt. Oh iya, di sini ada fungsi tambahan supaya agak lebih mudah bacanya.

def getIndeks(url):
    i = 1
    tautans = []
    tautan = getUrl(url)
    while (len(tautan) != 0):
        url = "http://indeks.kompas.com/indeks/index/news?p=%d" %i
        print url
        i += 1
        tautan = getUrl(url)
        tautans += tautan

    print len(tautans)
    bf = open(filelink, "w")
    for t in tautans:
        bf.write(t)
        bf.write("\n")
    bf.close()

Di kode ini, kita mengekstrak setiap tautan di halaman indeks dan menyimpan tautannya di berkas link-tanggal.txt. Cara ekstrak tautannya ada di fungsi kedua, yakni getUrl(url).

def getUrl(url):
    '''ambil url tiap berita di indeks'''
    tautan = []
    url = urllib.urlopen(url)

    result = url.read()
    url.close()
    soup = BeautifulSoup(result, "html.parser")

    for link in soup.find_all('h3'):
        for l in link.find_all('a'):
            isi = l.get('href')
            tautan.append(isi)
    return tautan

Nah di sini librari Bs4 mulai digunakan. Jadi url hasil tangkapan fungsi pertama akan dibaca sama librari urllib dan hasilnya disimpan di result. Lalu si result kita olah dengan librari Bs4 dan disimpan di soup. Di sini keajaiban Bs4 dimulai. halah.

Jadi si Bs4 akan mencari setiap tag h3 dari soup, lalu setelah itu dicari mana yang link, dalam hal ini tag a href. Hasilnya berupa link yang disimpan di isi, lalu dimasukkan ke list (atau array sih?) tautan. Lalu hasilnya dikembalikan ke fungsi pertama yang kemudian disimpan dalam bentuk file.

Oke, singkat kata kita sudah dapat kumpulan linknya. Setelah itu mari melangkah ke langkah kedua, membaca setiap link dan mengambil isinya. Ini tugas fungsi ketiga.

def getLinkFromFile():
    '''Ambil berita dari link yang sudah disimpan di link-tgl.txt'''
    print "Ambil berita dari link tanggal %s. " % today
    bf = open(filelink, 'r')
    i = 0
    for l in bf:
        print l
        getBerita(l)
        # i +=1
        # if i > 5:
        #     break
    bf.close()

Di sini ada fungsi baru lagi, yakni getBerita(url) yang menjalankan fungsi mengekstrak berita dari setiap link. Fungsi di atas hanya bertugas membuka berkas link-tanggal.txt dan mengekstrak setiap linknya untuk kemudian dilempar ke fungsi berikut.

def getBerita(url):
    url = urllib.urlopen(url)
    result = url.read()
    url.close()
    isiberita = ""
    
    soup = BeautifulSoup(result, "html.parser")
    for berita in soup.find_all('div', {'class':'kcm-read-text'}):
        isiberita += berita.get_text().encode("utf-8")
    bf = open(filename, 'a')
    bf.write(isiberita)
    bf.write("\n")
    bf.close()

Fungsi di atas sebenarnya mirip dengan fungsi getUrl(). bedanya, yang dicari bukan lagi tag h3 dan “a href”, tapi tag ‘div class=”kcm-read-text”‘, karena di sini naskah berita disimpan. Lalu nanti hasilnya dimasukkan ke berkas berita-tanggal.txt.

Mudah bukan? Ya iyalah mudah, ini kan aplikasi buat pra-newbie -_-

Ngomong-ngomong, kenapa pakai contoh kompas.com? Sebenarnya bebas sih, mau situs berita lain pun bisa. Saya sudah coba di situs detik.com dan *ehem* inilahkoran.com juga. Saya pakai contoh kompas.com karena kode html-nya lebih rapi sehingga lebih mudah dibaca :D.

Ini program lengkapnya:


4 responses to “Belajar python: Scraping situs”

    • halo, maaf saya ada kendala. saya dapat error seperti ini

      Traceback (most recent call last):
      File “komp.py”, line 71, in
      getIndeks(url)
      File “komp.py”, line 31, in getIndeks
      tautan = getUrl(url)
      File “komp.py”, line 20, in getUrl
      soup = BeautifulSoup(result, “html.parser”)
      TypeError: ‘module’ object is not callable

      apakah bisa dibantu menyelesaikan errornya?
      terimakasih

Ada komentar?

This site uses Akismet to reduce spam. Learn how your comment data is processed.