Day26 LINE BOT & NBA 战况查询

本次 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


<<:  [Day 26] Replication (4-3) - Leaderless Replication - Detecting Concurrent Writes & 结论

>>:  「Wordpress 外挂开发」制作多重role的外挂,让你的商业逻辑的可能性具现化

DBA 训练营 - SQL Server 资料库管理入门

数据资料与 Azure SQL 热潮来袭 升级资料库专业技能 Are You Ready? DBA ...

Parser Generator (三)

上篇提到了 parser generator 在产生程序码的时候,可以用四个步骤去拆解里面的资讯并...

[Day7] 提升

何谓提升(Hoisting)? 提升(Hoisting) 其实主要是为了厘清 JavaScript ...

Day.13 「初步学习 Javascript 基础篇」 —— Javascript 宣告变数 与 基本型别

前面已经大略介绍了 HTML 和 CSS 的入门知识了,接着我们要来认识 Javascript,来...

Day 20 - SwiftUI开发学习4(切换分页)

今天我们运用NavigationView去做切换视窗。 正文 建立新的页面 因为我们之前都是在主页去...