크롤러 만들기[3] - 웹 페이지 구현 및 수집 테스트 > Golang

Golang

크롤러 만들기[3] - 웹 페이지 구현 및 수집 테스트 정보

크롤러 만들기[3] - 웹 페이지 구현 및 수집 테스트

본문

했던 거 이어서 쓰겠습니다.

코드를 직접 치는거라 오타가 있을 수도 있습니다.

궁금한 점이나 문의..?? 등 댓글로 남겨주시면 제가 아는 선에서 설명드리겠습니다.

 

 

/public/crawl.html

- 목록 페이지 URL, 목록 정규표현식, 게시물 제목 정규표현식, 게시물 본문 정규표현식을 입력받습니다.


<!DOCTYPE HTML>
<html>
    <head>
        <title>크롤러</title>
    </head>
    <body>
        <form name="crawl" action="/crawl" method="post">
            <p>
                <input id="url" name="url" type="text">
                <label for="url">목록 페이지 URL</label>
           </p>
           <p>
               <input id="regex_url" name="regex_url" type="text">
               <label for="regex_url">목록 페이지 정규표현식</label>
           </p>
           <p>
               <input id="regex_subject" name="regex_subject" type="text">
               <label for="regex_subject">게시물 제목 정규표현식</label>
           </p>
           <p>
               <input id="regex_content" name="regex_content" type="text">
               <label for="regex_content">게시물 본문 정규표현식</label>
           </p>
           <button type="submit">
                실행
            </button>
        </form>
    </body>
</html>

 

이제 이 페이지에 있는 데이터를 받을 수 있는지 확인해봅시다.

 


$ go run .

 

1030332716_1675670586.323.png

 

이제 POST /crawl 라우트를 만들어봅시다.

기존에는 /app.go 에서 라우트를 설정했지만 이제 확장성을 위해 분리해봅시다.

 

/internal/rotues/public_route.go


package routes
 
import (
    "github.com/gofiber/fiber/v2"
)
 
func PublicRoutes(app *fiber.App) {
    app.Get("/crawl", func(c *fiber.Ctx) error {
        return c.Render("crawl", fiber.Map{})
    })
 
    app.Post("/crawl", func(c *fiber.Ctx) error {
        return c.SendString(c.FormValue("regex_url"))
    })
}

 

정상 작동하게 된다면 목록페이지 정규표현식에 입력한 값이 출력됩니다.

 

1030332716_1675670803.5267.png

 

작동하네요.

 

이제 컨트롤러를 등록해서 수집 테스트를 해봅시다.

web_controller.go -> 웹에서 데이터를 받고, 해당 데이터를 crawl_controller.go로 넘깁니다.

crawl_controller.go -> 넘겨받은 데이터를 이용해 수집합니다.

 

/app/controllers/web_controller.go


package controllers
 
import (
    "fmt"
    "github.com/gofiber/fiber/v2"
)
 
func PageCrawl(c *fiber.Ctx) error {
    return c.Render("crawl", fiber.Map{})
}
 
func Crawl(c *fiber.Ctx) error {
    url := c.FormValue("url") // 목록 페이지 URL
 
    reg := make(map[string]string) // 정규표현식 Map
    reg["url"] = c.FormValue("regex_url")
    reg["subject"] = c.FormValue("regex_subject")
    reg["content"] = c.FormValue("regex_content")
 
    result, err := crawl(url, reg)
    if err != nil {
        return c.SendString(err.Error()) // 에러 발생 시 에러 반환
    }
 
    return c.SendString(fmt.Sprintf("%v", result))
}

 

/app/controllers/crawl_controller.go


package controllers
 
import (
    "regexp"
    "strconv"
    "strings"
 
    "github.com/go-resty/resty/v2"
)
 
func crawl(url string, reg map[string]string) ([]string, error) {
    client := resty.New()
    url = strings.Split(url, ":page:")[0] // 목록 페이지 url에서 :page: 부분을 제거
 
    result, err := boardCrawl(client, url, reg["url"])
    if err != nil {
        return result, err
    }
 
    return result, nil
}
 
func boardCrawl(client *resty.Client, url string, regex string) ([]string, error) {
    urlResult := make([]string, 0)
 
    for i := 1; ; i++ {
        // 페이지 번호 붙이기
        strIndex := strconv.Itoa(i)
        resp, err := client.R().Get(url + strIndex)
        if err != nil {
            return urlResult, err
        }
 
        regex = `(?m)` + regex
 
        reg, err := regexp.Complie(regex)
        if err != nil { // 정규표현식에서 에러날 경우 에러 반환
            return urlResult, err
        }
 
        if len(reg.FindString(resp.String())) == 0 {
            break // 정규표현식에서 검출된 게 없을 때 벗어나기
        }
 
        for _, match := range reg.FindAllString(resp.String(), -1) {
            urlStr := strings.ReplaceAll(reg.FindStringSubmatch(match)[1], "&", "&")
            urlResult = append(urlResult, urlStr)
        }
    }
 
    return urlResult, nil
}

 

이제 해당 컨트롤러가 작동이 될 수 있도록 라우트를 수정해야 합니다.

 

/internal/routes/public_route.go


package routes
 
import (
    "example/crawler/app/controllers"
    "github.com/gofiber/fiber/v2"
)
 
func PublicRoutes(app *fiber.App) {
    app.Get("/crawl", controllers.PageCrawl)
    app.Post("/crawl", controllers.Crawl)
}

 

이 라우트 내용이 적용되어야 하므로 app.go 를 수정합시다.

 

/app.go


package main
 
import (
    "example/crawler/internal/configs"
    "example/crawler/internal/routes"
    "github.com/gofiber/fiber/v2"
)
 
func main() {
    app := fiber.New(configs.FiberConfig())
    routes.PublicRotues(app)
 
    app.Listen(":3000")
}

 

그럼 이제 테스트를 해봅시다./

 

터미널


$ go mod tidy
$ go run .

 

1030332716_1675672845.5553.png

 

URL 부분에 page 번호가 들어가는 부분에 :page:를 넣고, 정규표현식도 입력해서 실행한다면

 

1030332716_1675672888.583.png

 

짜란..

 

1030332716_1675672939.7175.png

약 202개의 목록 페이지를 가져오는데 900ms 가 나오네요.

추천
0

댓글 0개

전체 40 |RSS
Golang 내용 검색

회원로그인

진행중 포인트경매

  1. 참여4 회 시작24.04.25 20:23 종료24.05.02 20:23
(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT