Web Scraping with Go

Web Scraping adalah teknik untuk mengumpulkan data dari situs web yang melibatkan script dengan metode tertentu menyesuaikan data apa yang akan diambil. Umumnya web scraping digunakan untuk berbagai keperluan seperti analisis data, pengumpulan informasi dan masih banyak lagi.

Setup Go

Download Go untuk Linux melalui go.dev/dl

wget https://go.dev/dl/go1.23.2.linux-amd64.tar.gz

Kemudian extract archive ke /usr/local.

tar -xaf go1.23.2.linux-amd64.tar.gz -C /usr/local/

Selanjutnya edit file .bash_profile lalu tambahkan baris berikut.

export PATH=$PATH:/usr/local/go/bin

Setelah itu, Anda dapat mengecek versi Go dengan perintah.

$ go version
go version go1.23.2 linux/amd64

Example Script

Berikut adalah contoh script untuk menganalisi URL yang terdapat di dalam file list_url.txt berdasarkan list keyword yang ada di file list_keyword.txt.

Buat file scraper.go.

nano scraper.go

Lalu tambahkan kode berikut.

package main

import (
    "bufio"
    "fmt"
    "net/http"
    "io/ioutil"
    "os"
    "regexp"
    "strings"
    "sync"
)

func readLines(filePath string) ([]string, error) {
    file, err := os.Open(filePath)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    var lines []string
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        lines = append(lines, scanner.Text())
    }
    if err := scanner.Err(); err != nil {
        return nil, err
    }
    return lines, nil
}

func checkKeywords(url string, keywords []string, wg *sync.WaitGroup, results chan<- string) {
    defer wg.Done()
    resp, err := http.Get(url)
    if err != nil {
        results <- fmt.Sprintf("Error fetching URL: %s", url)
        return
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        results <- fmt.Sprintf("Error reading response body: %s", url)
        return
    }

    content := string(body)
    foundKeywords := []string{}

    for _, keyword := range keywords {
        re := regexp.MustCompile("(?i)" + regexp.QuoteMeta(keyword))
        if re.MatchString(content) {
            foundKeywords = append(foundKeywords, keyword)
        }
    }

    if len(foundKeywords) > 0 {
        results <- fmt.Sprintf("Kata %s ditemukan di %s", strings.Join(foundKeywords, " dan "), url)
    } else {
        results <- fmt.Sprintf("Tidak ada kata kunci yang ditemukan di %s.", url)
    }
}

func processBatch(urls []string, keywords []string, wg *sync.WaitGroup, results chan<- string) {
    for _, url := range urls {
        wg.Add(1)
        go checkKeywords(url, keywords, wg, results)
    }
    wg.Wait()
}

func main() {
    urls, err := readLines("list_url.txt")
    if err != nil {
        fmt.Println("Error reading URL file:", err)
        return
    }

    keywords, err := readLines("list_keyword.txt")
    if err != nil {
        fmt.Println("Error reading keyword file:", err)
        return
    }

    var wg sync.WaitGroup
    results := make(chan string, len(urls))

    batchSize := 100
    for i := 0; i < len(urls); i += batchSize {
        end := i + batchSize
        if end > len(urls) {
            end = len(urls)
        }
        batch := urls[i:end]
        processBatch(batch, keywords, &wg, results)
    }

    close(results)

    for result := range results {
        fmt.Println(result)
    }
}

Selanjutnya Anda dapat menambahkan beberapa URL ke dalam file list_url.txt dan beberapa keyword ke dalam file list_keyword.txt.

Jalankan script untuk memulai scraping.

go run scraper.go