Post List

2019년 3월 15일 금요일

R을 이용한 텔레그램봇 만들기 (스케쥴러를 사용하여 자동 정보 전송)


지난번 블로그에서는 R 프로그램과 텔레그램 메신저를 연결하는 방법을 알아보았습니다. 그러나 정보가 필요할 때마다 해당 코드를 직접 실행하는 일은 매우 번거로운 일입니다. 이번에는 스케쥴러를 사용하여 내가 원하는 시점마다 코드가 자동으로 실행되는 방법에 대해 알아보도록 하겠습니다.


library(telegram.bot)
bot = Bot(token = "Your API KEY")
updates = bot$getUpdates()
chat_id = updates[[1]]$message$chat$id


역시나 텔레그램방과 R을 연결하기 위해 테스트 메시지를 전송합니다. 그 후 이전과 동일하게 채팅방 id를 연결하도록 합니다.


library(lubridate)
bot$sendMessage(chat_id = chat_id, text = as.character(now()))


예시 메시지로 now() 즉 현재 시점의 날짜 및 시간을 전송해보도록 하겠습니다. 



현재 일자 및 시간이 제대로 전송되었습니다. 위에서 입력한 코드(텔레그램과 API연결 및 현재 시간 전송, 총 6줄)를 example_send_time.R 파일로 저장하도록 하겠습니다. 

이제 우리가 하고싶은 작업은 매 분, 매 시간, 혹은 매 월마다 미리 정해진 시점에 해당 R 코드를 실행하게 하는 것입니다. 이를 위해서는 taskscheduleR 이라는 패키지가 필요합니다. (윈도우OS 기준입니다.) 해당 패키지를 통해 특정 코드를 작업 스케쥴러에 등록 후, 저장된 시점마다 해당 코드가 자동으로 돌아가도록 만들 수 있습니다.


# install.packages('taskscheduleR')
library(taskscheduleR)
tele_auto = file.path("C:/Users/Henry/Dropbox/R/텔레그램봇/example_send_time.R")
taskscheduler_create(taskname = "send_time", rscript = tele_auto,
                     schedule = "MINUTE", 
                     starttime = format(Sys.time() + 61, "%H:%M"), 
                     startdate = format(Sys.time(), "%Y/%m/%d"),
                     modifier = 1)


먼저 tele_auto 부분에는 우리가 실행하고자 하는 코드의 위치를 입력해주도록 합니다. 그 후 taskscheduler_create() 함수를 이용하여 원하는 작업에 대한 구체적인 내용을 입력해주도록 합니다.

taskname은 작업 이름이며 rscript는 위에서 지정한 코드의 위치입니다. schedule은 스케쥴 주기를 의미하며 한번만 작업이 돌아가고자 할 때는 'ONCE', 일간 기준일 때는 'DAILY', 주간 기준일 때는 'WEEKLY', 분 기준일 때는 'MINUTE'을 입력합니다.
starttime은 시작 시간으로써, 위의 입력된 값은 현재 시간에서 61초 뒤부터 시작함을 의미합니다. startdate는 시작 일자로써, 오늘을 의미합니다. 마지막으로 modifier는 반복 주기로써 1은 1분당 한번 자동화가 실행됨을 의미합니다.

즉 위의 명령어는 tele_auto에 해당하는 코드를 send_time이라는 스케쥴러에 등록하고, 오늘 현재시점에서 61초부터 1분당 해당 작업을 실행한다는 의미입니다. 한번 코드를 실행해보도록 하겠습니다.



1분마다 현재 시간이 봇을 통해 전송되는 모습이 확인됩니다. 이를 통해 자동 스케쥴링이 매우 잘 작동함이 확인됩니다. 




윈도우 내의 '작업 스케쥴러'를 들어가보면, 우리가 설정한 작업인 send_time이 등록되어 있음이 확인됩니다. 


taskscheduler_stop('작업 이름')
taskscheduler_runnow('작업 이름')
taskscheduler_delete("작업 이름")


작업을 중간에 컨트롤 하는 명령어는 위와 같습니다. 먼저 taskscheduler_stop() 함수는 실행되는 작업을 중단시켜 주며, taskscheduler_runnow() 함수는 재실행 되도록 합니다. 마지막으로 taskscheduler_delete() 함수는 해당 작업을 삭제합니다.

이번에는 뭔가 더 실용적인 예제로써, 네이버 금융의 실시간 속보 중 상위 3개 뉴스를 매 분마다 보내주는 예제를 살펴보겠습니다.


library(telegram.bot)
bot = Bot(token = "704368869:AAHvB95bVddu94upcObtrKDT0QugPvYHqdM")
updates = bot$getUpdates()
chat_id = updates[[1]]$message$chat$id

# send news
library(httr)
library(rvest)

data = GET('https://finance.naver.com/news/news_list.nhn?mode=LSS2D&section_id=101&section_id2=258')

data.url = data %>% read_html(encoding = 'EUC-KR') %>%
  html_nodes('.newsList.top') %>%
  html_nodes('.articleSubject') %>%
  html_nodes('a') %>%
  html_attr('href') %>%
  .[1:3] %>%
  paste0('https://finance.naver.com', .)
    
sapply(data.url, function(x) {bot$sendMessage(chat_id = chat_id, x)})


위 코드는 네이버 금융의 속보 탭에서 상위 3개 기사의 url을 전송하는 코드입니다. 이를 naver_crawl.R 파일에 저장하도록 하겠습니다. 


library(taskscheduleR)
tele_auto = file.path("C:/Users/Henry/Dropbox/R/텔레그램봇/naver_crawl.R")

taskscheduler_create(taskname = "send_news", rscript = tele_auto,
                     schedule = "MINUTE", 
                     starttime = format(Sys.time() + 61, "%H:%M"), 
                     startdate = format(Sys.time(), "%Y/%m/%d"),
                     modifier = 1)

위와 거의 동일한 코드이며, taskscheduler_create() 함수를 통해 naver_crawl.R 코드가 자동으로 실행되도록 하겠습니다.



1분마다 상위 기사 3개가 텔레그램으로 전송되는 것이 확인됩니다.

지난번과 이번 포스팅을 통해 R과 텔레그램봇을 연결하는 방법, 그리고 스케쥴러를 사용하여 자동으로 원하는 정보를 전송하는 기능까지 알아보았습니다. 다음 시간에는 지난 번에 알아본 다트API를 이용한 공시정보 크롤링과 연동하여, 관심종목의 공시 내역을 실시간으로 텔레그램에 전송하는 방법에 대해 알아보도록 하겠습니다.

댓글 2개:

  1. 안녕하세요. epsis.kpx.or.kr 메인화면에서 5분마다 바뀌는 현재부하(MW) 숫자 데이터를 추출하려고 하는데,
    httr, rvest 패키지를 활용한 코드에 대해 자문해주실 수 있으신가요. 감사합니다.

    답글삭제
    답글
    1. telegram으로 추출하는 방식이 아니라, text, excel 형태로 추출하는 방법도 알고계시다면
      말씀 부탁드립니다.

      삭제