웹 스크래핑은 웹 페이지에서 데이터를 추출하는 작업을 의미합니다. Go 언어는 웹 스크래핑을 위한 강력한 툴을 제공하며, 이를 최대한 효율적으로 사용하여 성능을 향상시킬 수 있습니다. 이번 글에서는 Go 언어로 웹 스크래핑 시 성능을 향상시키기 위한 몇 가지 방법에 대해 알아보겠습니다.
1. 다중 고루틴 사용
고루틴은 Go 언어의 핵심 기능 중 하나로, 경량화된 스레드로 동시성을 구현할 수 있습니다. 웹 스크래핑 작업은 여러 개의 요청을 동시에 처리해야 하기 때문에, 고루틴을 사용하여 동시성을 활용할 수 있습니다. 이를 통해 CPU 사용량을 최대화하고 처리 속도를 향상시킬 수 있습니다.
package main
import (
"fmt"
"net/http"
"sync"
)
func scrapeWebsite(url string, wg *sync.WaitGroup) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error scraping website:", err)
return
}
// 웹 페이지 스크래핑 작업 수행
// ...
resp.Body.Close()
}
func main() {
urls := []string{"https://example.com", "https://google.com", "https://github.com"}
var wg sync.WaitGroup
wg.Add(len(urls))
for _, url := range urls {
go scrapeWebsite(url, &wg)
}
wg.Wait()
}
위 코드에서는 scrapeWebsite
함수를 고루틴으로 실행하고, sync.WaitGroup
을 사용하여 모든 고루틴이 작업을 완료할 때까지 기다립니다. 이를 통해 여러 웹 페이지를 동시에 스크래핑할 수 있습니다.
2. HTTP Keep-Alive 사용
HTTP Keep-Alive는 웹 서버와의 TCP 연결을 유지하는 기능입니다. 일반적으로 HTTP 요청 시마다 TCP 연결을 맺고 끊는 것은 오버헤드가 발생하므로, Keep-Alive를 사용하여 TCP 연결을 재사용할 수 있습니다. 이를 통해 웹 스크래핑 작업에서의 네트워크 지연을 줄일 수 있습니다.
package main
import (
"fmt"
"net/http"
)
func main() {
client := &http.Client{
Transport: &http.Transport{
MaxIdleConnsPerHost: 100,
},
}
urls := []string{"https://example.com", "https://google.com", "https://github.com"}
for _, url := range urls {
resp, err := client.Get(url)
if err != nil {
fmt.Println("Error scraping website:", err)
continue
}
// 웹 페이지 스크래핑 작업 수행
// ...
resp.Body.Close()
}
}
위 코드에서는 http.Transport
의 MaxIdleConnsPerHost
를 사용하여 동시에 유지할 수 있는 TCP 연결의 최대 개수를 설정합니다. 이렇게 하면 작업량이 많은 웹 스크래핑 작업에서도 TCP 연결을 효율적으로 재사용할 수 있습니다.
3. 적절한 캐싱 활용
웹 스크래핑 작업은 동일한 웹 페이지를 여러 번 요청하는 경우가 많습니다. 이 경우, 적절한 캐싱을 활용하여 중복 요청을 피할 수 있습니다. Go 언어에서는 GoCache와 같은 캐싱 라이브러리를 사용할 수 있습니다.
package main
import (
"fmt"
"net/http"
"time"
"github.com/patrickmn/go-cache"
)
var (
c = cache.New(5*time.Minute, 10*time.Minute)
)
func scrapeWebsite(url string) {
data, found := c.Get(url)
if found {
// 캐싱된 데이터 사용
fmt.Println("Using cached data for", url)
return
}
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error scraping website:", err)
return
}
// 웹 페이지 스크래핑 작업 수행
// ...
resp.Body.Close()
// 데이터 캐싱
c.Set(url, data, cache.DefaultExpiration)
}
func main() {
urls := []string{"https://example.com", "https://google.com", "https://github.com"}
for _, url := range urls {
go scrapeWebsite(url)
}
time.Sleep(time.Second * 5) // 스크래핑 작업이 완료될 때까지 대기
}
위 코드에서는 go-cache
패키지를 사용하여 데이터를 캐싱합니다. c.Get
을 통해 캐싱된 데이터를 가져오고, 캐시가 없는 경우에만 웹 페이지를 스크래핑합니다. 이를 통해 중복 웹 페이지 요청을 줄일 수 있습니다.
마무리
Go 언어로 웹 스크래핑 시 성능 향상을 위해 다중 고루틴 사용, HTTP Keep-Alive 활용, 그리고 적절한 캐싱을 활용하는 방법에 대해 알아보았습니다. 이러한 방법들을 적용하여 웹 스크래핑 작업의 성능을 최적화할 수 있습니다.