基於Python命令列的NBA文字直播小工具

kboypkb發表於2021-09-09

NBA季後賽正在進行中,無奈要上班,不能看影片直播。而文字直播頁面又有太多廣告之類的東西,所以花半天時間,用Python 3搞一個基於命令列的文字直播,看著清爽,又不容易被領導發現。效果如圖所示:

圖1:程式啟動時,列出當前所有比賽

圖片描述


圖2:輸入比賽ID後,文字直播來了

圖片描述


找了一圈NBA文字直播網站,發現有現成的介面,直接返回json格式資料。那就是它了,聽我慢慢道來。

首先在電腦瀏覽器開啟,我用的是chrome瀏覽器,在Network中可以看到,它不停地用GET方式請求,這個地址會返回當前正在進行的所有型別比賽的基本情況,根據其中的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後,點選某一場比賽,進入文字直播頁面。首先請求頁面,其中XXXX是上一步獲取的id,它會返回一個數字,即max_sid。然後判斷該max_sid是否大於上次獲取的該值,如果大於,表示有新的直播文字,否則表示沒有。

如果max_sid大於上一次的值,透過請求(其中XXXX是今天的日期,格式為2017-04-20YYYY是第一步中獲取的id),返回這場比賽的基本情況,比如比分,是第幾節等,如下所示:

{    "id": "96233",    "home_team": "勇士",    "visit_team": "開拓者",    "home_score": "110",    "visit_score": "81",    "period_cn": "第4節結束",
    ...
}

最後,就可以獲取直播的文字了。請求(其中XXXX是比賽idYYYYmax_sid),它會返回最新的直播文字,其中包括一條或多條直播文字,如下所示:

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

可以看到,該請求返回的資訊中沒有比賽剩餘時間、主隊和客隊等資訊,所以每次獲取直播文字之前,需要多一次請求,獲得比賽的基本資訊。

基本流程就是這樣,非常簡單,一共就四個GET請求,返回四串json,用requests庫請求,然後解析搞定。

先定義一個Match類,表示當前正在進行的每一場比賽。

# match.pyclass 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.pyclass 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 = ''# 某一場比賽當前的max_sidMatch_Max_Sid_Url = '%s/0.htm'# 某一場比賽最新文字直播Match_Living_Text_Url = '%s/0/lit_page_2/%d.htm'# 某一場比賽當前的基本情況Match_Info_Url = '%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 matchesdef 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 textsdef 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 matchesdef get_watch_match(matches):
    match_id = input('請輸入比賽ID:')    for match in matches:        if match.id == match_id:            return match    else:
        print('輸入的ID不正確')        return Nonedef 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上。



作者:lakerszhy
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1916/viewspace-2803078/,如需轉載,請註明出處,否則將追究法律責任。

相關文章