iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
1
自我挑戰組

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

Day27 LINE BOT & NBA - 賽程查詢

今天要來完成的是賽程查詢的部分
不過在實作過程當中發現到 今日賽程和今日戰況似乎沒有差異
再者,查詢特定時間區間賽程,礙於 Carousel 本身的限制,最多只能有 12 個 Bubble ,目前沒有想到好的解決方案

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

  • 查詢特定球隊賽程

構思

我們思考一下,使用者該如何獲取這些資料?
也就是,使用者該如何選擇特定球隊?

我們可以先做一個 Flex Message 包含所有球隊的名稱以及 logo
使用者可以藉由點擊來獲取球隊賽程資訊

那麼也就是說,我們需要的資料大致上有

  • 全部球隊資訊
  • 特定球隊基本資訊
  • 特定球隊賽程資訊

那麼,接下來我們來找找,在哪裡可以獲得這些資訊

網頁觀察

先到任意球隊的賽程頁面觀察,這裡選擇熱火隊 https://tw.global.nba.com/teams/schedule/#!/heat

使用 ctrl + shift + i 或是 F12 開啟開發者工具,將網頁重新整理後查看 Network 的 XHR

觀察後發現到對 https://tw.global.nba.com/stats2/team/schedule.json?countryCode=TW&locale=zh_TW&teamCode={TeamName} 發送 requests 後會得到該球隊在當前賽季的賽程資料

觀察 Responce 的內容
發現到他是以一個月分作為區間,裡面會標明在這個區間內比賽的詳細資訊

除了這份資料以外,我們還發現到在 Standing.json 中包含了該球隊的排名以及基本資料

接下來到 https://tw.global.nba.com/teamindex/ 來看看隊伍資訊
一樣開啟開發者工具,選擇 Network 的 XHR
發現到 conferenceteamlist.json 裡面包含了NBA 所有球隊資訊
並且是以 區 -> 組 的方式整理

獲取資料

對我們來說,重要的資料包含了

  • NBA球隊資料
    • 球隊名稱
    • 球隊 logo 連結
  • 球隊基本資料
    • 球隊名稱
    • 球隊簡稱
    • 球隊 logo 連結
    • 球隊區域排名
    • 球隊總教練
    • 當前賽季 W/L
  • 球隊賽程資料
    • 日期
    • 時間
    • 對手
    • 詳細資訊連結

接下來我們要寫三個 function

  • GetTeam.py
    取得 NBA 所有球隊資訊
  • GetAllSchedule.py
    取得特定球隊所有賽程資訊
  • GetDateSchedule.py
    取得特定球隊特定賽程資訊

一樣因為篇幅的關係,這裡不把所有的 code 貼出來
說明一下流程

GetTeam.py

這裡要取得 NBA 所有球隊資訊

先製作一個 Flex Message 版型
大致上希望會是以區域聯盟的組別區分

不過為了往後維護以及程式書寫上的方便,這邊將每個 Bubble 以及裡面的隊伍分開做了兩個 JSON

這裡的規劃是將球隊兩兩一組放入 Team ,再放入 Teams
最終用 Card 將每個 Teams 組合起來

接下來是程式碼的部分

  1. 發送 requests
  2. 接收 responce
  3. 依序將資料放入 Card 中並回傳

GetAllSchedule.py

這裡要取得特定隊伍的所有賽程資訊

先製作一個 Flex Message 版型
後面可以提供持續加入賽程

包含了兩個 JSON

將得到資料依照月份,每筆放入到 GameInfo.json 中,再放入 Schedule.json ,最終將每個月的 Schedule 放入 Card 回傳

接下來是程式碼的部分

  1. 發送 requests
  2. 接收 responce
  3. 將資料依序放入到 Card 當中並回傳

這邊特別注意到一個大坑QQ
在這裡會遇到時間上時區的問題
千萬千萬不要使用 dateTimeEt 做判斷
為甚麼呢?

根據 Yahoo奇摩知識+ 的某個問題, NBA 採用的是美國當地時間,會遇到於夏至時間的問題
處理這個會比較麻煩,所以千萬千萬不要用這個

我們可以用前一篇使用的方式,使用 utcMillis 做判斷可以保證其準確且時差上直接 +8 即可

def tz_from_utc_ms_ts(utc_ms_ts, tz_info):
    """Given millisecond utc timestamp and a timezone return dateime

    :param utc_ms_ts: Unix UTC timestamp in milliseconds
    :param tz_info: timezone info
    :return: timezone aware datetime
    """
    # convert from time stamp to datetime
    utc_datetime = datetime.datetime.utcfromtimestamp(utc_ms_ts / 1000.)

    # set the timezone to UTC, and then convert to desired timezone
    return utc_datetime.replace(tzinfo=pytz.timezone('UTC')).astimezone(tz_info)

GetDateSchedule.py

這裡要取得特定隊伍的特定賽程資訊

我們一樣先設計一個 Flex Message 的版型

包含了兩個 JSON

主要是因為不確定各個按鈕是否存在,所以將按鈕的區塊特意拉出來

接下來是程式碼的部分
其實步驟相同

  1. 發送 requests
  2. 接收 responce
  3. 將資料依序放入到 Card 當中並回傳

跟前一個一樣,需要注意時差的問題,記得一定要使用 utcMillis 做判斷,不要用 dateTimeEt

Rich Menu

最後要稍微修改一下我們的 Rich Menu
將第三個 Buttom 改成 球隊賽程

成果

最終測試結果如下:

  • 球隊賽程

  • 特定球隊賽程

  • 特定球隊特定賽程

後記

這好像是我第二次踩到時差的坑了QQ
真的超級麻煩,還好裡面有提供 utcMillis ,不然會哭出來w
很趕的把今天這篇完成了
日後會再稍微修飾一下內容
希望大家玩得開心w

參考資料

本次練習 Github 連結
Yahoo奇摩知識+
LINE Flex Message Simulator
NBA
W3schools HTML color Picker


上一篇
Day26 LINE BOT & NBA 戰況查詢
下一篇
Day28 LINE BOT & NBA - 球員數據查詢
系列文
LINE BOT 新手村30日攻略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言