iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
1
自我挑戰組

LINE BOT 新手村30日攻略系列 第 26

Day26 LINE BOT & NBA 戰況查詢

  • 分享至 

  • xImage
  •  

本次 Github 連結

我們在這個區塊要完成的功能有:

  • 查詢今日戰況
  • 查詢特定日期戰況

網頁觀察

首先一樣到網站上看看 https://tw.global.nba.com/scores/#!/2020-10-10
開啟開發者工具,可以使用 ctrl+shift+i 或是 F12 在瀏覽器中開啟
開啟後將網頁重新整理,在 Network 的部分觀察一下
選擇了 XHR 之後,在裡面發現到了 daily.json
原來網頁是從這裡取得戰況的

透過上述的 Request URL 可以發現到,只要在後面接上查詢的日期,就可以獲取資料
那麼資料的格式如何呢?
我將 Responce 複製到 VSCode 上查看,這裡截了一張圖

在這邊資料包含了

  • homeTeam
    主隊相關數據
  • awayTeam
    客隊相關數據
  • urls
    包含了 直播 HIGHLIGHT 連結
  • profile
    標示了該比賽的 場地 時間 主客隊 季數
  • boxscore
    標示了該局比賽的 雙方比分 比賽時長 比賽狀態

那麼如果比賽尚未開始會是如何呢?
發現到 boxscore status1 ,並且很多數值都會是 null

那麼如果該日沒有比賽呢?
date 參數會直接變成 null

小叮嚀: Python 裡面是沒有 null 的,但是可以用 None 表示

另外要特別注意,一天的比賽可能不只一場w

那麼大致上了解後,我們可以準備開始 coding 了

獲取資料

對我們來說重要的資訊包含

  • 主客隊
    • 名稱
    • 所屬城市
    • 所屬區域
    • 四節比分
    • 總結分數
    • 目前總計 W/L 數量
    • 得分/籃板/助攻王
  • 連結
    • 直播
    • HIGHTLIGHT
  • 比賽資訊
    • 場地
    • 日期
    • ID

我寫了一個 function 來獲取這些資料,並同時做成 Carousel 回傳
但是 Code 有點冗長,畢竟 JSON 內容有點大量,所以這邊就不貼出來了,詳細可以到 Github 上查看

主要的流程如下

  1. 讀取日期
  2. 前往 https://tw.global.nba.com/stats2/scores/daily.json?countryCode=TW&gameDate={查詢日期}&locale=zh_TW&tz=%2B8
  3. 將結果轉成 JSON 物件
  4. 將所有需要的資料取出,並以變數儲存
  5. 檢查當天是否有比賽
    1. 有,並且已經結束
      比賽結果以 Carousel 回傳
    2. 有,並且尚未開始
      主客隊資訊以及賽前分析連結以 Carousel 回傳
    3. 沒有
      未來最近一次比賽日期以 Carousel 回傳

光是在這個部分,我就做了3個 Flex Message ,分別是三種狀況
參考 JSON 連結

另外說明一下我的 JSON 是怎麼包的
BubbleCard 的單元,每個 Bubble 都會 append 到 Card 裡面

GameButtomBubble 的單元,是為了避免有部分比賽只有部分資訊,最後 append 到 Bubblefooter

Score 也是 Bubble 的單元,是為了避免部分比賽有 OT 的狀況,以利於後續 append

Rich Menu

接下來我們要來設定使用者如何獲取資料,這裡使用 Rich Menu
首先到 https://manager.line.biz/ 找到圖文選單

簡單設定一下

按鈕的部分,目前我先選了6個,但是實際上今天會用到的只有兩個,分別是

  • 本日戰績
  • 過去戰績

這兩者皆是回傳文字訊息
圖片的部分我是直接在上面的建立圖片簡單設計一下

Main

接下來是主程式的設計,基本架構都跟之前相同
我們要處理的只有文字訊息,分別是 本日戰績 過去戰績
使用 Flex Message 的方式跟以往相同,使用了 Bubble.json 以及 Carousel.json 來處理

如果使用者詢問的是過去戰績,我們就回傳一個按鈕,當使用者點及按鈕後會觸發 postback action
而我們之後再來處理這部分

# Message event
@handler.add(MessageEvent)
def handle_message(event):
    message_type = event.message.type
    user_id = event.source.user_id
    reply_token = event.reply_token
    
    if(message_type == 'text'):
        message = event.message.text
        if(message == '過去戰績'):
            Buttom = json.load(open('json/Buttom.json','r',encoding='utf-8'))
            line_bot_api.reply_message(reply_token, FlexSendMessage('請選擇時間', Buttom))

如果使用者詢問的是本日戰績
我們先將今天的日期以格式 YY:MM:DD 放入剛剛設計好的 function
最後直接以 Flex Message 回覆即可

        elif(message == '本日戰績'):
            nowtime = datetime.datetime.now()
            today = '{}-{}-{}'.format(nowtime.year,nowtime.month,nowtime.day)
            Card = Get_Card(today)
            line_bot_api.reply_message(reply_token, FlexSendMessage('查詢結果出爐~',Card))

目前成果

  • 本日戰績
    剛好今天沒有比賽,所以顯示出最近一場的比賽

    點擊查詢下一場

  • 過去戰績

    查詢了 2011-12-17

那麼今天的部分就大致完成囉!

後記

聽說
下禮拜是段考ㄟ QQQQQQQQQQQ
不過第一次做這個還是挺有趣的,雖然說真的做到快累死ㄌ
資料蠻大量的,而且裡面有許多專業術語,導致在理解我有哪些資料花了不少時間
另外在設計的過程當中也是跳了很多坑w
我還在思考有沒有優化的方式可以讓我在使用 Bubble 的過程可以輕鬆一點w
總之還是希望大家玩得開心w

參考資料

今日練習 Github 連結
W3schools HTML Color Picker
LINE Developer - datetime picker action
NBA
初學者看懂 NBA 數據
stackoverflow - Python - converting UTC millisecond timestamp to local time
Flex Message Simulator


上一篇
Day25 LINE BOT & NBA
下一篇
Day27 LINE BOT & NBA - 賽程查詢
系列文
LINE BOT 新手村30日攻略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言