基於Python命令列的NBA文字直播小工具
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-20
,YYYY
是第一步中獲取的id
),返回這場比賽的基本情況,比如比分,是第幾節等,如下所示:
{ "id": "96233", "home_team": "勇士", "visit_team": "開拓者", "home_score": "110", "visit_score": "81", "period_cn": "第4節結束", ... }
最後,就可以獲取直播的文字了。請求(其中
XXXX
是比賽id
,YYYY
是max_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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於命令列的工作管理員 Taskwarrior命令列
- Python實現用命令列看虎撲直播Python命令列
- 基於python的文字轉圖片工具Python
- 基於Golang的CLI 命令列程式開發Golang命令列
- 基於命令列的WINCE驅動開發工具命令列
- 用Node.js寫的看股票的命令列小工具Node.js命令列
- 基於node和npm的命令列工具——tive-cliNPM命令列
- 命令列與Shell -> 文字處理命令之sed命令列
- 基於 JavaFx 搭建的實用小工具集合Java
- 命令列基礎命令列
- Procrastinate:基於PostgreSQL的Python任務佇列ASTSQLPython佇列
- 用於構建優秀命令列的 4 個 Python 庫命令列Python
- 基於 Yeoman 定製的互動式命令列腳手架命令列
- python解析命令列Python命令列
- Linux 命令列下的最佳文字編輯器Linux命令列
- Windows命令列基礎Windows命令列
- 分享一個MySQL命令列自動完成和補全的小工具MySql命令列
- 基於事理圖譜的文字推理
- 基於python+ffmpeg的視訊併發直播壓力測試Python
- Windows從命令列建立文字檔案的兩種方式Windows命令列
- 基於 Laravel 命令列開發 API 程式碼生成器Laravel命令列API
- 簡單解析C++基於Boost庫實現命令列C++命令列
- 基於asyncio和redis的Python分散式任務佇列RedisPython分散式佇列
- 使用 Python 生成基於馬爾可夫鏈的偽隨機文字Python馬爾可夫隨機
- python命令列如何退出Python命令列
- 基於支援向量機的文字分類文字分類
- Win7 如何複製cmd命令列文字Win7命令列
- 看圖理解基於陣列的佇列陣列佇列
- 基礎篇:一文講懂樹莓派命令列文字編輯工具Vim的使用樹莓派命令列
- 手把手 | 基於TextRank演算法的文字摘要(附Python程式碼)演算法Python
- Go小工具系列——判斷元素是否存在於陣列中Go陣列
- python小工具Python
- Python 命令列之旅 —— 初探 argparsePython命令列
- Python 開發命令列工具Python命令列
- python控制windows命令列程式PythonWindows命令列
- Linux基礎命令---文字過濾colrmLinux
- Linux基礎命令---文字統計pasteLinuxAST
- Linux基礎命令---wc文字統計Linux