前言
相傳,就在前幾日,在網上閑逛時,刷到了一個猜歌的小程序。這個小程序通過播放歌曲部分片段,然后讓用戶來猜它的歌名,大概是這樣的:
作為一個腦熱的聽歌愛好者,于是他越陷越深,越刷越得勁。可是,他的 「排名竟一直上不去」!正當他惆悵之際,一個絕妙的想法 「ding」的一下就出現了,學會了它,媽媽再也不用擔心他的排名上不去了!
一、思路分析
為了搞清楚猜歌的過程是什么樣的,首先通過抓包來對請求和響應進行分析。在PC版微信中打開小程序,然后通過Fiddler進行抓包。我們會發現猜歌的過程由兩個請求構成。 (ps.當然也可以直接抓手機端的包,但是由于各種原因,會相對復雜一些)一個是 「獲取歌曲的相關信息」(包括答案)。對!你沒有聽錯,返回的數據直接包括了猜歌的答案,請求如下:
這是一個get請求,包括了用于登陸驗證的 「token」、 「user_id」等,返回的結果為歌曲相關的信息,其中最重要的是 「answer」(紅圈部分)。
另一個是 「發送猜歌請求」,如下:
這同樣是一個get請求,也包含了token等參數,還包含了提交的答案 「answer」和歌曲的 「sid」。通過返回的 「is_right」字段便可以判斷是否猜對。(1則猜對,否則不對)
那么,思路已經很明晰了:通過python編寫程序,首先獲取歌曲的答案,然后將答案提交。
二、獲取答案
首先定義一個類:
classguessStar:
def__init__(self,token,userId):
'''
初始化函數
'''
self.token = token # 用戶token
self.userId = userId # 用戶ID
隨后,根據抓包的請求定義一個獲取答案的函數:
defget_answer(self):
'''
獲取答案函數
'''
url = 'https://api.zuiqiangyingyu.net/index.php/api/guess_v2/Index'
headers = { 'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat',
'content-type': 'application/json',
'Accept-Encoding': 'gzip, deflate, br'}
params = (( 'token',self.token), # 用戶token,需要換成自己的
( 'user_id',self.userId), # 用戶ID,需要換成自己的
( 'wechat_type', 'wechat_song'))
res = requests.get(url,headers=headers,params=params) # 發送請求
data = res.json # 獲取返回結果(json格式)
music = data[ 'd'][ 'list'][ 0] # 音樂數據
sid = music[ 'id'] # 音樂ID
answer = music[ 'answer'] # 對應的答案
return(sid,answer)
這個請求很簡單,只需要將數據包對于的url、參數、請求頭等模擬出來即可。
三、提交答案
同樣,通過抓包分析后定義一個提交答案的函數:
defguess(self,sid,answer):
'''
猜歌函數
'''
url= 'https://api.zuiqiangyingyu.net/index.php/api/guess_v2/Sub'
headers = { 'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat',
'content-type': 'application/json',
'Accept-Encoding': 'gzip, deflate, br'}
params = (( 'token',self.token), # 用戶token,需要換成自己的
( 'user_id',self.userId), # 用戶ID,需要換成自己的
( 'sid',sid), # 音樂ID
( 'answer',answer), # 答案
( 'wechat_type', 'wechat_song'))
res = requests.get(url,headers=headers,params=params)
result = res.json[ 'd'][ 'user'][ 'is_right'] # 猜歌的結果
returnresult
函數返回的是is_right字段,如果是1則表示答案正確,否則則是錯誤的。
四、猜猜猜
有了get_answer和guess函數,我們便可愉快地開始自動化猜歌答題了,定義如下函數:
defdo_guess(self,num):
'''
進行猜歌(通過num指定次數)
'''
N = 0
whileTrue:
sid,answer = self.get_answer
result = self.guess(sid,answer)
ifresult == '1': # 如果猜對
N += 1
print( '第%s首歌回答正確!'%sid)
else:
print( '第%s首歌回答錯誤!'%sid)
ifN >= num: # 如果達到指定次數
break
其中num參數表示猜歌的次數。在主函數中調用它:
if__name__ == '__main__':
star = guessStar( 'xxxx', 'xxx')
star.do_guess( 1001) # 開始猜歌
xxxx分別表示賬號的token和用戶ID,這里需要大家換成自己的。所謂 「一千零一夜」,于是我也跑1001次好了,run一下:
在運行之前,我是這樣的:
運行之后,我是這樣的:
沒有錯,我的排名正在噌噌噌地往上升!!舒服了~~
寫在最后
我想本篇文章的真正意義可能不在于代碼本身,而是希望為大家提供更加廣泛的思路:
Python不僅是課堂上紛繁復雜的理論知識,還能為我們的生活提供便利;
Python不僅是項目中枯燥無味的日復一日,還能為我們的生活帶來歡;
Python不僅是成長里孜孜不倦的埋頭苦學,還能為我們的生活增添成就;
無論是Python、Java、C#,乃至攝影、繪畫。whatever,它們都是我們興趣或是謀生的技能。我想,只有真正的 「熱愛它們」,它們也才能在我們的生活中更好地結出盛果、生根發芽!