크롤러 만들기[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 .
이제 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"))
})
}
정상 작동하게 된다면 목록페이지 정규표현식에 입력한 값이 출력됩니다.
작동하네요.
이제 컨트롤러를 등록해서 수집 테스트를 해봅시다.
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 .
URL 부분에 page 번호가 들어가는 부분에 :page:를 넣고, 정규표현식도 입력해서 실행한다면
짜란..
약 202개의 목록 페이지를 가져오는데 900ms 가 나오네요.
!-->!-->!-->!-->!-->!-->!-->!-->0
댓글 0개