#ホークスのスタメン速報をslack連携してみた
さぁ皆さんプロ野球が開幕しましたね!
あけましておめでとうございます。
##さてさて
プロ野球といえば、まずは試合開始前にスタメンがどうなっているかが気になりますよね?(よね!?)
でも、スタメン発表って17時半前だったりして仕事してると見れない!
試合始まって、やっとスタメンがわかるとか、やだ!
そうだ!slackで通知すればいいんだ!
ついでなのでjavaで書こう!
##というわけで
書いた
import java.io.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.text.ParseException;
import java.lang.InterruptedException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Stamen {
public static void main(String[] args) throws IOException ,ParseException {
String channel = args[0];
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String strDate = sdf.format(cal.getTime());
SimpleDateFormat checksdf = new SimpleDateFormat("M月d日");
String checkDate = checksdf.format(cal.getTime());
//確認ファイルがいたら何もしない
String dir = new File(".").getAbsoluteFile().getParent();
String filePath = dir + "/tmp/" + strDate + ".txt";
File newfile = new File(filePath);
if (newfile.exists()) {
System.out.println("処理終了(既に処理済)");
return;
}
//某サイトより情報を拝借
String schedule_url = "http://○○/?date=" + strDate;
Document document = Jsoup.connect(schedule_url).get();
//日付情報を取得
String target_date_info = document.select("div#day_nav").select(".LinkCenter").text();
if(!target_date_info.matches(checkDate + ".*")) {
System.out.println("処理終了(不正な日付)");
return;
}
Elements tables = document.select("table.teams");
//選手単位
Boolean gameflag = false;
String gameurl = "";
String team1 = "";
String team2 = "";
for (Element table : tables) {
Elements teams = table.select("td.yjMS");
team1 = table.select("tr:nth-child(1) td.yjMS").text();
team2 = table.select("tr:nth-child(2) td.yjMS").text();
for (Element team : teams) {
if (team.text().equals("ソフトバンク")){
gameflag = true;
String target_href = table.select("td.yjMSt a").attr("href");
if (target_href.equals("")){
System.out.println("処理終了(ゲーム前など)");
return;
}
//某サイトのゲームのTOP画面のURLを作成
gameurl = "http://○○" + target_href + "top";
}
}
if (gameflag == true){
break;
}
}
//ゲーム自体がないので
if (gameflag == false) {
try{
newfile.createNewFile();
System.out.println("処理終了(ゲームがありません)");
return;
}catch(IOException e){
System.out.println(e);
}
}
if (!gameurl.equals("")){
String alltext = "";
alltext = checkDate + "のスタメン" + "\\r\\n";
Document game_document = Jsoup.connect(gameurl).get();
//スタメン
Elements team1_dom = game_document.select("#yjSNLiveStartingmember div.column-right");
Elements team2_dom = game_document.select("#yjSNLiveStartingmember div.column-left");
if (team1_dom.text().equals("") || team2_dom.text().equals("")) {
System.out.println("処理終了(試合開始前)");
return;
}
alltext += team1 + "\\r\\n";
alltext += stamenCheck(team1_dom) + "\\r\\n";
alltext += "\\r\\n";
alltext += team2 + "\\r\\n";
alltext += stamenCheck(team2_dom) + "\\r\\n";
//処理が一回完了してたらファイルを作成して作らせないようにする + 必要なJSONを作成する
try{
newfile.createNewFile();
FileWriter filewriter = new FileWriter(newfile);
String jsontext = "payload={\"channel\": \"#" + channel + "\", \"username\": \"hawks_stamen\", \"text\": \"" + alltext + "\", \"icon_emoji\": \":baseball:\"}";
filewriter.write(jsontext);
filewriter.close();
}catch(IOException e){
System.out.println(e);
}
//slack実行
String command = "/usr/bin/curl -X POST https://hooks.slack.com/services/○○(webhookのURL) -d @" + filePath;
Process process = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(process
.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
}
private static String stamenCheck(Elements team_dom){
String text = "";
Elements team1_fielder_dom = team_dom.select("table:nth-child(2)");
for (int i = 1; i <= 9; i++) {
Elements player_dom = team1_fielder_dom.select("tr:nth-child(" + (2 + i) + ")");
String player_no = player_dom.select("td:nth-child(1)").text();
String player_position = player_dom.select("td:nth-child(2)").text();
String player_name = player_dom.select("td:nth-child(3)").text();
text += player_no + player_position + player_name + "\\r\\n";
}
Elements team1_pitcher_dom = team_dom.select("table:nth-child(1)");
Elements pitcher_dom = team1_pitcher_dom.select("tr:nth-child(3)");
String pitcher_no = pitcher_dom.select("td:nth-child(1)").text();
String pitcher_position = pitcher_dom.select("td:nth-child(2)").text();
String pitcher_name = pitcher_dom.select("td:nth-child(3)").text();
text += pitcher_no + pitcher_position + pitcher_name + "\\r\\n";
return text;
}
}
結果
出来た!
技術的なお話
名将ポイントと同様にJsoupを利用してHTMLから情報を取得しました。
今回苦労したことは、slack連携とcron実行。
何時も通りslack連携をexecしようず!ってやったらどうにもうまくいかない。
- payloadのjson文法エラー
- コマンドが長すぎエラー?(正体がよくわかっていない)
ばっかりでていつまでたってもslackに投稿できない・・・。
コマンド自体を出力して、そのままコマンドライン上で実行したら問題なく動作するのに・・・。
結局データ部分を外部ファイルに外出しして実行することで解消。
・・・したらcronで動作したら途中でエラーばっか。
環境変数がどうしてもうまく読み切れず、最終的にはbashでjavaを実行することでとりあえず解消。
(何か微妙だけど動けばよかったのでモウマンタイ)
まとめ
やっぱ野球ネタは楽しい!