Go 언어로 HTML을 스크래핑하여 기차 지연 정보를 가르쳐주는 Slack-bot 만들기
사실은 마음대로 중얼거리는 방식으로 하고 싶었습니다만 우선 이 시점에서 기사로 합니다.
(그 중 개조할지도.)
슬랙 앱 만들기
이 사이트를 참조하여 만들었습니다.
Golang에서 Slack Interactive Message를 사용하여 Bot 작성
bot 만들기
스크래핑할 패키지 설치
goquery를 설치합니다.
jQuery적인 조작을 할 수 있으므로 경험이 있는 Web 엔지니어에게는 비교적 이해할 수 있습니다.
$ go get github.com/PuerkitoBio/goquery
정보를 얻는 웹사이트
여기가 없으면 시작되지 않습니다.
이번은 Yahoo!노선 정보 씨로부터 취득합니다.
구현
그럼 실제로 코딩하여 앱을 만듭니다.
「운행 상황」이라는 키워드에 반응해 상기 사이트로부터 운행 상황을 돌려주는 bot입니다.
slack_bot.gopackage main
import (
"log"
"os"
"net/url"
"github.com/nlopes/slack"
"github.com/PuerkitoBio/goquery"
)
// HTMLをスクレイピングして運行状況のテキストを取得する
func getRailwayText() string {
_url := "https://transit.yahoo.co.jp/traininfo/area/4/"
doc, err := goquery.NewDocument(_url)
if err != nil {
panic(err)
}
u := url.URL{}
u.Scheme = doc.Url.Scheme
u.Host = doc.Url.Host
var message string
// まずはテーブル要素を取得する
doc.Find("div.trouble > table > tbody").Each(func(_ int, s *goquery.Selection) {
// 次にtrを掘っていく
s.Children().Each(func(idx int, ss *goquery.Selection) {
// idx==0は見出し列なので飛ばす
if (idx > 0) {
railway := ss.Children().Find("a").Text()
status := ss.Children().Find("span.colTrouble").Text()
detail := ss.Children().Next().Next().Text()
message = message + status + " @ " + railway + " (" + detail + ")\n"
}
})
})
return message
}
func run(api *slack.Client) int {
rtm := api.NewRTM()
go rtm.ManageConnection()
for {
select {
case msg := <-rtm.IncomingEvents:
switch ev := msg.Data.(type) {
case *slack.HelloEvent:
log.Print("Hello Event")
case *slack.MessageEvent:
switch ev.Text {
case "運行状況":
message := getRailwayText()
rtm.SendMessage(rtm.NewOutgoingMessage(message, ev.Channel))
case "help":
rtm.SendMessage(rtm.NewOutgoingMessage("Usage: 運行状況 関東圏の電車の運行状況を表示します。\n 他の機能?ないよ。", ev.Channel))
}
case *slack.InvalidAuthEvent:
log.Print("Invalid credentials")
return 1
}
}
}
}
func main() {
api := slack.New("YOUR TOKEN")
os.Exit(run(api))
}
토큰은 Slack API 페이지의 왼쪽 메뉴 [OAuth & Permissions]의 [Bot User OAuth Access Token]에 있습니다.
실행
그럼 로컬 터미널에서 움직입니다.
$ go run slack_bot.go
2019/05/03 11:03:27 Hello Event
Hello Event가 표시되면 성공입니다.
실제로 만든 bot에 대해 메시지를 보냅니다.
제대로 돌아왔습니다!
끝에
goquery는 원하는 객체의 검색 조건을 지정하는 것만으로 마음대로 와 주므로 매우 편리했습니다.
복수의 사이트로부터 정보를 취득하는 경우라도 Go 유익한 병행 처리로 효율적으로 처리하거나 할 수 있을 것 같네요.
slack-bot도 확장성이 높고, 궁리에 따라 다양한 곳에서 효율화를 할 수 있을 것 같습니다.
참고
Go와 goquery로 스크래핑
Reference
이 문제에 관하여(Go 언어로 HTML을 스크래핑하여 기차 지연 정보를 가르쳐주는 Slack-bot 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/higuo/items/3bc9a3d06a445ca18754
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
스크래핑할 패키지 설치
goquery를 설치합니다.
jQuery적인 조작을 할 수 있으므로 경험이 있는 Web 엔지니어에게는 비교적 이해할 수 있습니다.
$ go get github.com/PuerkitoBio/goquery
정보를 얻는 웹사이트
여기가 없으면 시작되지 않습니다.
이번은 Yahoo!노선 정보 씨로부터 취득합니다.
구현
그럼 실제로 코딩하여 앱을 만듭니다.
「운행 상황」이라는 키워드에 반응해 상기 사이트로부터 운행 상황을 돌려주는 bot입니다.
slack_bot.go
package main
import (
"log"
"os"
"net/url"
"github.com/nlopes/slack"
"github.com/PuerkitoBio/goquery"
)
// HTMLをスクレイピングして運行状況のテキストを取得する
func getRailwayText() string {
_url := "https://transit.yahoo.co.jp/traininfo/area/4/"
doc, err := goquery.NewDocument(_url)
if err != nil {
panic(err)
}
u := url.URL{}
u.Scheme = doc.Url.Scheme
u.Host = doc.Url.Host
var message string
// まずはテーブル要素を取得する
doc.Find("div.trouble > table > tbody").Each(func(_ int, s *goquery.Selection) {
// 次にtrを掘っていく
s.Children().Each(func(idx int, ss *goquery.Selection) {
// idx==0は見出し列なので飛ばす
if (idx > 0) {
railway := ss.Children().Find("a").Text()
status := ss.Children().Find("span.colTrouble").Text()
detail := ss.Children().Next().Next().Text()
message = message + status + " @ " + railway + " (" + detail + ")\n"
}
})
})
return message
}
func run(api *slack.Client) int {
rtm := api.NewRTM()
go rtm.ManageConnection()
for {
select {
case msg := <-rtm.IncomingEvents:
switch ev := msg.Data.(type) {
case *slack.HelloEvent:
log.Print("Hello Event")
case *slack.MessageEvent:
switch ev.Text {
case "運行状況":
message := getRailwayText()
rtm.SendMessage(rtm.NewOutgoingMessage(message, ev.Channel))
case "help":
rtm.SendMessage(rtm.NewOutgoingMessage("Usage: 運行状況 関東圏の電車の運行状況を表示します。\n 他の機能?ないよ。", ev.Channel))
}
case *slack.InvalidAuthEvent:
log.Print("Invalid credentials")
return 1
}
}
}
}
func main() {
api := slack.New("YOUR TOKEN")
os.Exit(run(api))
}
토큰은 Slack API 페이지의 왼쪽 메뉴 [OAuth & Permissions]의 [Bot User OAuth Access Token]에 있습니다.
실행
그럼 로컬 터미널에서 움직입니다.
$ go run slack_bot.go
2019/05/03 11:03:27 Hello Event
Hello Event가 표시되면 성공입니다.
실제로 만든 bot에 대해 메시지를 보냅니다.
제대로 돌아왔습니다!
끝에
goquery는 원하는 객체의 검색 조건을 지정하는 것만으로 마음대로 와 주므로 매우 편리했습니다.
복수의 사이트로부터 정보를 취득하는 경우라도 Go 유익한 병행 처리로 효율적으로 처리하거나 할 수 있을 것 같네요.
slack-bot도 확장성이 높고, 궁리에 따라 다양한 곳에서 효율화를 할 수 있을 것 같습니다.
참고
Go와 goquery로 스크래핑
Reference
이 문제에 관하여(Go 언어로 HTML을 스크래핑하여 기차 지연 정보를 가르쳐주는 Slack-bot 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/higuo/items/3bc9a3d06a445ca18754
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Go와 goquery로 스크래핑
Reference
이 문제에 관하여(Go 언어로 HTML을 스크래핑하여 기차 지연 정보를 가르쳐주는 Slack-bot 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/higuo/items/3bc9a3d06a445ca18754텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)