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


<<:  Day 29|Divi 功能练习 21 Fullwidth Menu Module 全宽选单设定

>>:  Day 27 初学者补给站 学习方向讨论

Day30 居然到了这一天

完全没想到一转眼第30天就这样到来了,从开赛前的信心满满,总觉得可以将脑袋里的东西通通有条理地讲出来...

D21 - TiDB监控

TiDB除了使用prometheus与grafana两个老司机搜集资料,另外还提供了一套dashbo...

[2021铁人赛 Day19] General Skills 16

引言 特别的一题... 这题大家的评分不高,我想应该真的出得不好 不过也意外让我学到这个新东西~ ...

15. Error x Exception x Bug Trackers

初学阶段对错误处理没什麽感觉(尽管几乎所有程序语言书都有这一章节),写的都是不用维护的小专案、没有真...

DAY 3 新增 Git 来为版本进行管控

为什麽要用 git Git 是一个好用的分散式版本控管软件,在我们要开始写 html 之前,推荐要先...