코딩/GoLang

GoLang에서 URL 파싱하기

드리프트 2021. 1. 26. 20:30
728x170

 

 

안녕하세요?

 

Go 언어(GoLang)은 웹 개발에 아주 유용한 언어인데요.

 

웹 개발에서 가장 중요한 URL 파싱에 대해 예제를 통해 알아 보겠습니다.

 

 

위 그림처럼 먼저 URL 구조체의 구성요소에 대해 알고 있어야 합니다.

 

Scheme, Opaque, User, Host, Path, RawPath, ForceQuery, RawQuery, Fragment, RawFragment가 있습니다.

 

각각의 예제는 아래 코드를 참조해서 이해하면 빠릅니다.

package main

import (
	"fmt"
	"log"
	"net"
	"net/url"
	"strings"
)

func main() {

	// URL 파싱을 위한 예제 URL을 모은 스트링 타입의 슬라이스입니다.
	// 각종 예제를 위해 어려운 URL만 모아 놨습니다.
	var links = []string{"https://analytics.google.com/analytics/web/#embed/report-home/a98705171w145119383p149829595/",
		"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
		"https://bob:pass@testing.com/country/state",
		"http://www.golangprograms.com/",
		"mailto:John.Mark@testing.com",
		"https://www.google.com/search?q=golang+print+string+10+times&oq=golang+print+string+10+times&aqs=chrome..69i57.8786j0j8&sourceid=chrome&ie=UTF-8",
		"urn:oasis:names:description:docbook:dtd:xml:4.1.2",
		"https://stackoverflow.com/jobs?med=site-ui&ref=jobs-tab",
		"ssh://mark@testing.com",
	}

	// URL 예제를 for range 루프를 통해서 한개 한개 분석할 예정입니다.
	for _, link := range links {

		// 첫번째 출력
		// 해당 URL 전체를 프린트합니다.
		fmt.Println("URL:", link)

		// 본격적인 URL 파싱입니다.
		// go 기본 모듈인 url의 Parse 메서드를 이용합니다.
		// url.Parse 는 파싱 에러가 날때는 nil 이나 err를 리턴하고
		// 정상적으로 파싱됐을 때는 해당 ResolveReference를 리턴합니다.
		// 여기서 ResolveReference 는 u 변수로 받았습니다.
		u, err := url.Parse(link)

		// url.Parse 에러 발생시
		if err != nil {
			log.Println(err)

			// for range 루프에서 다음 link를 파싱하라고 continue 문구를 사용
			continue
		}

		// parserURL 함수는 밑에 우리가 만든 함수입니다.
		// ResolveReference 인 u 참조를 받습니다.
		parserURL(u)

		// 한개의 link 파싱이 끝날때 마다 #을 50개씩 출력해 라인을 구분합니다.
		fmt.Println(strings.Repeat("#", 50))
		fmt.Println()
	}
}

 

위 코드는 main 함수만 일단 적었습니다.

 

각 코드의 설명은 주석을 참조하면 됩니다.

 

그리고 참고사항으로 url.Parse는 다음과 같이 정의 되어 있습니다.

 

 

위 그림을 보시면 URL 타입의 참조를 리턴하고 있습니다.

 

그래서 우리의 parserURL 함수는 다음과 같이 참조를 파라미터로 갖게 됩니다.

 

func parserURL(u *url.URL)

 

이제 parserURL 함수를 마저 살펴 보겠습니다.

// 우리가 만든 parserURL 함수입니다.
// main 함수에서 ResolveReference 참조인 u 변수를 받아서
// 각종 메서드를 이용해 해당 정보를 출력합니다.
// 변수 u는 참조라서 url.URL 앞에 *로 표시합니다.
func parserURL(u *url.URL) {
    // Scheme 출력
    fmt.Println("Scheme:", u.Scheme)
    
    // Opaque 가 있으면 출력
	if u.Opaque != "" {
		fmt.Println("Opaque:", u.Opaque)
    }
    
    // User 가 있으면 출력
	if u.User != nil {

        // User 구조체의 메서드인 Username() 을 호출해서 Username 출력
        fmt.Println("Username:", u.User.Username())
        
        // User 구조체의 메서드인 Password() 를 호출해서 Password 출력
		if pwd, ok := u.User.Password(); ok {
			fmt.Println("Password:", pwd)
		}
    }
    
    // Host 가 있으면 출력
	if u.Host != "" {

        // Port가 포함되어 있을 때, 없을 때 구분하여 출력
		if host, port, err := net.SplitHostPort(u.Host); err == nil {
			fmt.Println("Host:", host)
			fmt.Println("Port:", port)
		} else {
			fmt.Println("Host:", u.Host)
		}
    }
    
    // Path가 있을 때 출력
	if u.Path != "" {
		fmt.Println("Path:", u.Path)
    }
    
    // RawQuery 가 있을 때 출력
	if u.RawQuery != "" {
        fmt.Println("RawQuery:", u.RawQuery)
        
        // RawQuery를 ParseQuery로 파싱해서
		m, err := url.ParseQuery(u.RawQuery)
		if err == nil {

            // key, value 값으로 출력
			for k, v := range m {
				fmt.Printf("Key: %q Values: %q\n", k, v)
			}
		}
    }
    
    // Fragment가 있을 때 출력
	if u.Fragment != "" {
		fmt.Println("Fragment:", u.Fragment)
	}
}

 

위 코드의 실행 결과는 아래와 같습니다.

 

 

이상으로 GoLang의 URL Parse에 대해 알아 보았습니다.

그리드형