테스트 사이트 - 개발 중인 베타 버전입니다

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

· 2년 전 · 802

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

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

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

 

 

/public/crawl.html

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

[code]

<!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>

[/code]

 

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

 

[code]

$ go run .

[/code]

 

1030332716_1675670586.323.png

 

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

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

 

/internal/rotues/public_route.go

[code]

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"))

    })

}

[/code]

 

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

 

1030332716_1675670803.5267.png

 

작동하네요.

 

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

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

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

 

/app/controllers/web_controller.go

[code]

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))

}

[/code]

 

/app/controllers/crawl_controller.go

[code]

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], "&amp;", "&")

            urlResult = append(urlResult, urlStr)

        }

    }

 

    return urlResult, nil

}

[/code]

 

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

 

/internal/routes/public_route.go

[code]

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)

}

[/code]

 

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

 

/app.go

[code]

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")

}

[/code]

 

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

 

터미널

[code]

$ go mod tidy

$ go run .

[/code]

 

1030332716_1675672845.5553.png

 

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

 

1030332716_1675672888.583.png

 

짜란..

 

1030332716_1675672939.7175.png

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

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

게시글 목록

번호 제목
92
82
80
79
78
77
76
75
72
65
64
63
62
57
55
54
53
52
51
50
46
44
43
39
34
29
28
27
26
22