네이버 뉴스 검색 애플리케이션

간단한 애플리케이션을 만들어 봅니다. koscrap 패키지를 이용해서 네이버 뉴스 검색 애플리케이션을 만듭니다.

유충현 https://choonghyunryu.github.io (한화생명)
2022-02-06

들어가기

공격이 최선의 방어라는 격투기 격언이 있습니다. Shiny의 경우는 실제로 애플리케이션을 개발해 보는 것이 최선의 학습 입니다.
간단하지만, 유용한 애플리케이션을 만들어 볼까요? 걱정할 필요 없습니다. 천천히 따라오세요

애플리케이션 설계

기능 설계

네이버 뉴스 검색 애플리케이션의 기능은 다음과 같이 정의합니다.

사용자 인터페이스 설계

애플리케이션 코드

UI Side

# UI Side
ui <- fluidPage(
    # Application title
    titlePanel("네이버 뉴스 검색 애플리케이션"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            textInput("client_id", 
                      label = h4("Client ID:"), 
                      value = ""),
            textInput("client_secret", 
                      label = h4("Client Secret:"), 
                      value = ""),            
            textInput("keyword", 
                      label = h4("검색 키워드:"), 
                      value = ""),
            radioButtons("sort", label = h4("정렬 옵션:"),
                         choices = list("날짜순" = "date", "유사도순" = "sim"), 
                         selected = "date"),           
            sliderInput("max_record", label = h4("검색 건수:"), min = 0, 
                        max = 500, value = 100, step = 100),
            actionButton("search_keyword", label = "뉴스 검색", 
                         icon = icon("newspaper")),
            width = 3
        ),

        # Reactable에 검색 결과 리스트업
        mainPanel(
            reactableOutput("news_list"),
            width = 9
        )
    )
)

Server Side

# Server Side
server <- function(input, output) {
    newsList <- reactiveValues(
        list = data.frame(
            title = character(0),
            description = character(0),
            publish_date = character(0),
            link = character(0),
            stringsAsFactors = FALSE
        ) %>% 
            reactable(
                defaultColDef = colDef(
                    align = "left"
                ),
                columns = list(
                    title = colDef(
                        name = "타이틀",
                        width = 250,
                    ),
                    description = colDef(name = "뉴스내용 요약"),
                    publish_date = colDef(
                        name = "뉴스 계시시간",
                        width = 150,
                    ),
                    link = colDef(
                        name = "뉴스 링크",
                        width = 250,
                        html = TRUE,
                        cell = function(url) {
                            htmltools::tags$a(href = as.character(url), target = "_blank", as.character(url))
                        }
                    )    
                ),
                showPageSizeOptions = TRUE,
                pageSizeOptions = c(5, 10, 15), 
                defaultPageSize = 5,
                bordered = TRUE,
                highlight = TRUE
            )    
    )
    
    output$news_list <- renderReactable({
        newsList$list
    })
    
    observeEvent(input$search_keyword, {
        # 3개의 텍스트는 반드시 입력해야 함
        req(input$keyword)
        req(input$client_id)
        req(input$client_secret)

        result <- koscrap::search_naver(
                query = input$keyword,
                sort  = input$sort,
                chunk = min(input$max_record, 100),
                max_record = input$max_record,
                do_done = TRUE,
                client_id = input$client_id,
                client_secret = input$client_secret) %>%
                mutate(title = title_text) %>%
                mutate(description = description_text) %>%
                mutate(publish_date = stringr::str_remove_all(publish_date,
                                                              "[[:alpha:]]")) %>%
                select(title, description, publish_date, link) %>% 
        reactable(
            defaultColDef = colDef(
                align = "left"
            ),
            columns = list(
                title = colDef(
                    name = "타이틀",
                    width = 250,
                ),
                description = colDef(name = "뉴스내용 요약"),
                publish_date = colDef(
                    name = "뉴스 계시시간",
                    width = 150,
                ),
                link = colDef(
                    name = "뉴스 링크",
                    width = 250,
                    html = TRUE,
                    cell = function(url) {
                        htmltools::tags$a(href = as.character(url), target = "_blank", as.character(url))
                    }
                )    
            ),
            showPageSizeOptions = TRUE,
            pageSizeOptions = c(5, 10, 15), 
            defaultPageSize = 5,
            bordered = TRUE,
            highlight = TRUE
        )
        
        newsList$list <- result
    })
}

사용 패키지 및 애플리케이션 호출

사용 패키지

애플리케이션 호출

# Run the application 
shinyApp(ui = ui, server = server)

애플리케이션 실행

애플리케이션 실행 화면

애플리케이션을 실행하면 다음과 같의 화면을 얻을 수 있습니다.

네이버 뉴스 검색 애플리케이션

뉴스링크 원문 조회하기

네번째 컬럼인 뉴스링크는 뉴스 원문의 URL 정보입니다. 이 URL을 클릭하면, 뉴스의 원문을 읽을 수 있습니다. 다음은 특정 페이지의 뉴스를 링크를 클릭하여 열린 웹 페이지입니다. 네이버 뉴스 검색 애플리케이션에서 불평등이라는 키워드로 검색하였기 때문에, 불평등이란 단어를 검색하였더니 1개 단어가 매칭되었습니다.

네이버 뉴스 링크의 뉴스 원문

Citation

For attribution, please cite this work as

유충현 (2022, Feb. 6). 애플리케이션 서버 구축을 위한 R 워크샾: 네이버 뉴스 검색 애플리케이션. Retrieved from https://choonghyunryu.github.io/workshop_lecture/news_app

BibTeX citation

@misc{유충현2022네이버,
  author = {유충현, },
  title = {애플리케이션 서버 구축을 위한 R 워크샾: 네이버 뉴스 검색 애플리케이션},
  url = {https://choonghyunryu.github.io/workshop_lecture/news_app},
  year = {2022}
}