美文网首页python开发python零零散散
基于Python命令行的NBA文字直播小工具

基于Python命令行的NBA文字直播小工具

作者: lakerszhy | 来源:发表于2017-04-20 14:44 被阅读968次

    NBA季后赛正在进行中,无奈要上班,不能看视频直播。而文字直播页面又有太多广告之类的东西,所以花半天时间,用Python 3搞一个基于命令行的文字直播,看着清爽,又不容易被领导发现。效果如图所示:

    图1:程序启动时,列出当前所有比赛

    图2:输入比赛ID后,文字直播来了

    找了一圈NBA文字直播网站,发现手机版直播吧有现成的接口,直接返回json格式数据。那就是它了,听我慢慢道来。

    首先在电脑浏览器打开手机版直播吧,我用的是chrome浏览器,在Network中可以看到,它不停地用GET方式请求http://bifen4m.qiumibao.com/json/list.htm,这个地址会返回当前正在进行的所有类型比赛的基本情况,根据其中的type字段过滤掉非NBA比赛就OK了。其中最重要的是ID字段,之后的所有操作都需要用到。返回的数据如下所示:

    {
        "code": "2760624",
        "second": "10",
        "list": [
            {
                "id": "96233",
                "sdate": "2017-04-20",
                "time": "10:30",
                "url": "/zhibo/nba/2017/042096233.htm",
                "type": "basketball",
                "start": "2017-04-20 10:30",
                "home_team": "勇士",
                "visit_team": "开拓者",
                "home_score": "106",
                "visit_score": "81",
                "period_cn": "第4节\n01:30",
                "from": "dc.live",
                "code": "373",
                "update": "13:13:37",
                "big_score_1": "",
                "big_score_2": ""
            },
            ... # 省略了其它比赛的信息
        ]
    }
    

    获得所有正在进行的比赛ID后,点击某一场比赛,进入文字直播页面。首先请求http://dingshi4pc.qiumibao.com/livetext/data/cache/max_sid/XXXX/0.htm页面,其中XXXX是上一步获取的id,它会返回一个数字,即max_sid。然后判断该max_sid是否大于上次获取的该值,如果大于,表示有新的直播文字,否则表示没有。

    如果max_sid大于上一次的值,通过请求http://bifen4pc2.qiumibao.com/json/XXXX/YYYY.htm(其中XXXX是今天的日期,格式为2017-04-20YYYY是第一步中获取的id),返回这场比赛的基本情况,比如比分,是第几节等,如下所示:

    {
        "id": "96233",
        "home_team": "勇士",
        "visit_team": "开拓者",
        "home_score": "110",
        "visit_score": "81",
        "period_cn": "第4节结束",
        ...
    }
    

    最后,就可以获取直播的文字了。请求http://dingshi4pc.qiumibao.com/livetext/data/cache/livetext/XXXX/0/lit_page_2/YYYY.htm(其中XXXX是比赛idYYYYmax_sid),它会返回最新的直播文字,其中包括一条或多条直播文字,如下所示:

    [
        {
            "live_id": "8769977",
            "live_text": "@仙女最库阿-:库里正负值最高32我去!!!!",
            "home_score": "110",
            "visit_score": "81",
            "pid_text": "比赛结束",
            ...
        },
        ... # 可能有多条直播文字
    ]
    

    可以看到,该请求返回的信息中没有比赛剩余时间、主队和客队等信息,所以每次获取直播文字之前,需要多一次请求,获得比赛的基本信息。

    基本流程就是这样,非常简单,一共就四个GET请求,返回四串json,用requests库请求,然后解析搞定。

    先定义一个Match类,表示当前正在进行的每一场比赛。

    # match.py
    
    class Match:
        def __init__(self, **kwargs):
            self.id = kwargs['id']
            self.home_team = kwargs['home_team']
            self.visit_team = kwargs['visit_team']
            self.home_score = kwargs['home_score']
            self.visit_score = kwargs['visit_score']
            self.period_cn = kwargs['period_cn'].replace('\n', ' ')
    
        def __repr__(self):
            return '{self.id} {self.home_team} {self.home_score} - {self.visit_score} {self.visit_team} {self.period_cn}'.format(self=self)
    

    再定义一个TextLiving类,表示获取的每一条文字直播。

    # text_living.py
    
    class TextLiving:
        def __init__(self, match_info, **kwargs):
            self.home_team = match_info['home_team']
            self.visit_team = match_info['visit_team']
            self.period_cn = match_info['period_cn']
            self.live_text = kwargs['live_text']
            self.home_score = kwargs['home_score']
            self.visit_score = kwargs['visit_score']
    
        def __repr__(self):
            return '{self.home_team} {self.home_score} - {self.visit_score} {self.visit_team} {self.period_cn}\n{self.live_text}\n{sep}'.format(self=self, sep='*'*60)
    

    接着创建zhibo8_api.py模块,用于获取相关数据。

    # 当前正在进行的比赛
    Living_Matches_Url = 'http://bifen4m.qiumibao.com/json/list.htm'
    
    # 某一场比赛当前的max_sid
    Match_Max_Sid_Url = 'http://dingshi4pc.qiumibao.com/livetext/data/cache/max_sid/%s/0.htm'
    # 某一场比赛最新文字直播
    Match_Living_Text_Url = 'http://dingshi4pc.qiumibao.com/livetext/data/cache/livetext/%s/0/lit_page_2/%d.htm'
    # 某一场比赛当前的基本情况
    Match_Info_Url = 'http://bifen4pc2.qiumibao.com/json/%s/%s.htm'
    
    
    def get_living_matches():
        response = requests.get(Living_Matches_Url)
        result = json.loads(response.text)
        matches = [Match(**match) for match in result['list'] if match['type'] == 'basketball' and match['period_cn'] != '完赛']
        return matches
    
    
    def get_match_max_sid(match_id):
        response = requests.get(Match_Max_Sid_Url % match_id)
        if response.status_code == requests.codes.ok:
            return int(response.text)
    
    
    def get_match_living(match_id, max_sid):
        # 先获取比赛的当前情况,再获取最新文字直播
        match_info = get_match_info(match_id)
    
        response = requests.get(Match_Living_Text_Url % (match_id, max_sid))
    
        texts = []
        if response.status_code == requests.codes.ok:
            result = json.loads(response.text)
            texts = [TextLiving(match_info, **living) for living in result]
        return texts
    
    
    def get_match_info(match_id):
        today = datetime.now().strftime('%Y-%m-%d')
        response = requests.get(Match_Info_Url % (today, match_id))
        match_info = json.loads(response.text)
        return match_info
    

    最后,在main.py模块中启动程序,开始直播!

    def get_living_matches():
        matches = zhibo8_api.get_living_matches()
        for match in matches:
            print(match)
        return matches
    
    def get_watch_match(matches):
        match_id = input('请输入比赛ID:')
        for match in matches:
            if match.id == match_id:
                return match
        else:
            print('输入的ID不正确')
            return None
    
    def main_loop():
        matches = get_living_matches()
        if len(matches) == 0:
            print('当前没有比赛!!!')
            return
    
        match = get_watch_match(matches)
        if not match:
            print('没去找到该比赛')
            return
    
        current_match_max_sid = -1
        while True:
            match_max_sid = zhibo8_api.get_match_max_sid(match.id)
            if not match_max_sid:
                print('没有直播数据')
                return
                
            if current_match_max_sid == match_max_sid:
                continue
    
            current_match_max_sid = match_max_sid
            text_livings = zhibo8_api.get_match_living(match.id, current_match_max_sid)
            for text in text_livings:
                print(text)
    
    if __name__ == '__main__':
        main_loop()
    

    程序中基本没做异常处理,还有很多需要改进的地方,欢迎大家指教。如果有朋友需要,我会把代码放在GitHub上。

    相关文章

      网友评论

      本文标题:基于Python命令行的NBA文字直播小工具

      本文链接:https://www.haomeiwen.com/subject/qprlzttx.html