Go

[Go] HTTP Client 크롤링 최적화

_HelloWorld_ 2025. 1. 22. 13:35

http.Client에 재사용 가능한 Transport 설정

현재 코드에서는 HTTP 요청을 처리할 때 http.Client를 기본적으로 사용하고 있는데, 이 클라이언트를 효율적으로 구성하면 성능 향상에 도움이 됨


Transport

http.Client는 내부적으로 연결을 재사용하기 때문에, 연결 풀 크기 및 설정을 최적화하면 요청 속도를 크게 향상]

var defaultTransport = &http.Transport{
    MaxIdleConns:        100,
    MaxConnsPerHost:     100,
    IdleConnTimeout:     90 * time.Second,
    TLSHandshakeTimeout: 10 * time.Second,
}

var httpClient = &http.Client{
    Transport: defaultTransport,
}

GZIP 압축 사용

서버가 GZIP 압축을 지원한다면 요청 헤더에 Accept-Encoding을 추가하여 응답 데이터를 압축하면 네트워크 전송 속도를 줄일 수 있음

// 기본 헤더와 쿠키를 처리하는 함수들
var defaultHeaders = map[string]string{
    "Host":            "cache-api.office.hiworks.com",
    "Origin":          "https://home.office.hiworks.com",
    "Referer":         "https://home.office.hiworks.com/",
    "Accept":          "application/json, text/plain, */*",
    "Accept-Encoding": "gzip", // 요고 추가
    "Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
    "Connection":      "keep-alive",
    "User-Agent":      "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
}

Request 핸들러 함수에 옵션 추가

// GET 요청 함수
func GetRequest(url string, cookies map[string]string) ([]byte, error) {
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return nil, err
    }

    // 기본 헤더 및 쿠키 추가
    addDefaultHeader(req)
    addCookies(req, cookies)

    // 요청 실행
    res, err := httpClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // Gzip 응답인지 확인 후 처리
    if res.Header.Get("Content-Encoding") == "gzip" {
        return decodeGzipBody(res.Body)
    }

    // 일반 응답 처리
    return io.ReadAll(res.Body)
}

응답 데이터가 gzip인지 확인하고 이코딩 하여 byte로 변환하여 Response

decodeGzipBody 함수:

  • Gzip으로 압축된 응답 데이터를 해제합니다.
  • gzip.NewReader를 사용하여 압축을 해제하고, 데이터를 읽습니다.

각 요청 함수에서 Content-Encoding 헤더 확인:

  • Content-Encoding이 gzip인 경우 decodeGzipBody를 호출합니다.
  • 그렇지 않으면 일반 데이터를 읽습니다.