多線程以后再打吧
記在開頭:如果req返回不是200不要慌,先試一下下面的方法
404:請求頭,
503:訪問頻繁加一個time.sleep:
206:似乎和200一樣不過它代表網頁可以緩存
還不對?換個ip或cookie?
千千音樂
爬之前不得不噴一下,千千版權真少,加載真慢...
步驟|思路:
首先要能爬取一首歌然后再爬取歌單的第一面,最后爬取可選擇的頁數
爬取一首歌首先要找到network里的media 里面如果有東西則可發現這才是這首歌真實的 播放|下載 地址 然后根據xcode來搜索(倒推)它的下載源比如有 songlink,ting...等類似的文件,進去后preview可以看到歌曲的各種介紹,最后爬進這個下載源獲得歌曲下載鏈接等數據 即可
坑點:
(我認為)json文件是像字典一樣的所以開頭結尾要是{}如果{}前后有東西要先正則除去,之后才能json.loads(xxx)否則會報錯說什么不是json格式(這里百度的話答案都是 ‘ 叫你該單引號 ’ 之類的然鵝實際上是上面的問題)
如果request.get(url,parama,headers).text='' .content=b''則說明header要加referer參數(被反爬了)
下載一首歌
播放一首歌后就可以看到這個mp3文件,點進去就是下載這首歌
def qianqian_download_mp3(song_name,song_artist,song_api): ''' 下載音樂 :return: ''' res = requests.get(song_api) res.encoding = res.apparent_encoding req = res.content with open(song_name + '-' + song_artist + '.mp3', 'wb') as f: f.write(req) path = os.getcwd() print(song_name + '-' + song_artist + ' 成功下載到' + path) time.sleep(1.5) return
找到歌的id
對比不同的歌發現只有xcode和MP3前面那個字符串改變推測這就和id有關的東西
找到所有歌的id
因為歌單肯定包含所有歌的id所以我們直接找歌單就行了,但是出大問題,xcode和那串字符搜索不到!!!
我找半天最后發現在千千音樂盒里面才有songlist和songlink
而這里面的songlist是你聽過的歌
songlink里面什么都有|歌詞地址,歌曲地址...
再觀察url是一個post類型
data參數發現是songid也就是說我們只要有songid就可以為所欲為了
假如我們已經有了songid那么可以先寫出get_song_api的代碼
def get_qianqian_song_api(song_nameid): ''' 得到千千音樂歌曲的下載地址 :param song_nameid: :param song_keyid: :return: ''' url = 'http://play.taihe.com/data/music/songlink' data = { 'songIds': '%s'%song_nameid, 'hq': '0', 'type': 'm4a,mp3', 'rate': '', 'pt': '0', 'flag': '-1', 's2p': '-1', 'prerate': '-1', 'bwt': '-1', 'dur': '-1', 'bat': '-1', 'bp': '-1', 'pos': '-1', 'auto': '-1', } header = { 'Accept': 'application/json, text/javascript, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Content-Length': '114', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Cookie': 'BAIDUID=39467BA490578EC38644901B14F6C417:FG=1; flash_tip_pop=true; app_vip=show; tipToTaihe=1; UM_distinctid=171a0f546b6835-04de0099ddf7e4-4313f6a-e1000-171a0f546b7acb; log_sid=158754725356639467BA490578EC38644901B14F6C417; sort-guide-showtimes=2; sort-guide-lastshow=1587547252753; Hm_lvt_2b0f0945031c52df2a103f3ed5d7c3aa=1587543328,1587543572,1587547253,1587547334; Hm_lpvt_2b0f0945031c52df2a103f3ed5d7c3aa=1587548461', 'Host': 'play.taihe.com', 'Origin': 'http://play.taihe.com', 'Pragma': 'no-cache', 'Referer': 'http://play.taihe.com/?__m=mboxCtrl.playSong&__a=2113234&__o=song/||songListIcon&fr=web||play.taihe.com&__s=%E6%9E%97%E4%BF%8A%E6%9D%B0', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', } req = requests.post(url, headers=header, data=data) text = req.json() return text['data']['songList'][0]['songLink']
下面我們就找song_nameid了
進入一首歌的頁面
直接搜索發現網頁html源碼就有有版權的song_nameid!!!
就是不太好處理...隨便正則搞一搞
def get_qianqian_song_list(key_word,page): url='http://music.taihe.com/search/song?s=1&key='+key_word+'&jump=0&start='+str((page-1)*20)+'&size=20&third_type=0' header={ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Cookie': 'BAIDUID=39467BA490578EC38644901B14F6C417:FG=1; u_lo=0; u_id=; u_t=; flash_tip_pop=true; app_vip=show; tipToTaihe=1; UM_distinctid=171a0f546b6835-04de0099ddf7e4-4313f6a-e1000-171a0f546b7acb; CNZZDATA1262632547=358279739-1587539552-http%253A%252F%252Fmusic.taihe.com%252F%7C1587539552; Hm_lvt_d0ad46e4afeacf34cd12de4c9b553aa6=1587543138,1587543339,1587543455,1587545349; tracesrc=web%7C%7Cplay.taihe.com; log_sid=158754534871539467BA490578EC38644901B14F6C417; __qianqian_pop_tt=6; Hm_lpvt_d0ad46e4afeacf34cd12de4c9b553aa6=1587546565', 'Host': 'music.taihe.com', 'Pragma': 'no-cache', 'Referer': 'http://music.taihe.com/', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36' } req = requests.get(url, headers=header) res = req.text song_ids = re.findall(r'"sid":(\d+),"', res) return song_ids
改變歌手名字
這只用改keyword就行了
改變頁碼來獲得普遍性結果
根據規律頁面改變至於start有關
page-1=start/20
完整代碼
暫時只支持搜索歌手
看class就知道大概了吧
順便把歌詞也弄到了|lrk_api 不過沒有下
如果有興趣也可以嘗試自己下下來
#-*- coding:utf-8 -*- # @Author : Dummerfu # @Time : 2020/4/22 16:54 import requests import os from bs4 import BeautifulSoup import time import re import json class Song_info(object): def __init__(self): self.song_name='' self.song_nameid='' self.artist_name='' self.lrk_api='' self.belong='' self.song_api='' def qianqian_download_mp3(song_name,song_artist,song_api): ''' 下載音樂 :return: ''' res = requests.get(song_api) res.encoding = res.apparent_encoding req = res.content with open(song_name + '-' + song_artist + '.mp3', 'wb') as f: f.write(req) path = os.getcwd() print(song_name + '-' + song_artist + ' 成功下載到' + path) time.sleep(1.5) return def get_qianqian_song_list(key_word,page): url='http://music.taihe.com/search/song?s=1&key='+key_word+'&jump=0&start='+str((page-1)*20)+'&size=20&third_type=0' header={ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Cookie': 'BAIDUID=39467BA490578EC38644901B14F6C417:FG=1; u_lo=0; u_id=; u_t=; flash_tip_pop=true; app_vip=show; tipToTaihe=1; UM_distinctid=171a0f546b6835-04de0099ddf7e4-4313f6a-e1000-171a0f546b7acb; CNZZDATA1262632547=358279739-1587539552-http%253A%252F%252Fmusic.taihe.com%252F%7C1587539552; Hm_lvt_d0ad46e4afeacf34cd12de4c9b553aa6=1587543138,1587543339,1587543455,1587545349; tracesrc=web%7C%7Cplay.taihe.com; log_sid=158754534871539467BA490578EC38644901B14F6C417; __qianqian_pop_tt=6; Hm_lpvt_d0ad46e4afeacf34cd12de4c9b553aa6=1587546565', 'Host': 'music.taihe.com', 'Pragma': 'no-cache', 'Referer': 'http://music.taihe.com/', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36' } req = requests.get(url, headers=header) res = req.text song_ids = re.findall(r'"sid":(\d+),"', res) return song_ids def get_single_song_info(song_nameid): ''' 得到千千音樂歌曲的下載地址 :param song_nameid: :param song_keyid: :return: ''' url = 'http://play.taihe.com/data/music/songlink' data = { 'songIds': '%s'%song_nameid, 'hq': '0', 'type': 'm4a,mp3', 'rate': '', 'pt': '0', 'flag': '-1', 's2p': '-1', 'prerate': '-1', 'bwt': '-1', 'dur': '-1', 'bat': '-1', 'bp': '-1', 'pos': '-1', 'auto': '-1', } header = { 'Accept': 'application/json, text/javascript, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Content-Length': '114', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Cookie': 'BAIDUID=39467BA490578EC38644901B14F6C417:FG=1; flash_tip_pop=true; app_vip=show; tipToTaihe=1; UM_distinctid=171a0f546b6835-04de0099ddf7e4-4313f6a-e1000-171a0f546b7acb; log_sid=158754725356639467BA490578EC38644901B14F6C417; sort-guide-showtimes=2; sort-guide-lastshow=1587547252753; Hm_lvt_2b0f0945031c52df2a103f3ed5d7c3aa=1587543328,1587543572,1587547253,1587547334; Hm_lpvt_2b0f0945031c52df2a103f3ed5d7c3aa=1587548461', 'Host': 'play.taihe.com', 'Origin': 'http://play.taihe.com', 'Pragma': 'no-cache', 'Referer': 'http://play.taihe.com/?__m=mboxCtrl.playSong&__a=2113234&__o=song/||songListIcon&fr=web||play.taihe.com&__s=%E6%9E%97%E4%BF%8A%E6%9D%B0', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', } req = requests.post(url, headers=header, data=data) text = req.json() return text['data']['songList'][0] def get_song_info_from_qianqian(song_info,tot,qianqian_song_list): ''' 得到每個歌曲的info :param song_info: :param tot: :param kuwo_song_list: :return: ''' for i in qianqian_song_list: song=get_single_song_info(i) song_info[tot].song_nameid=i song_info[tot].song_api=song['songLink'] song_info[tot].artist_name=song['artistName'] song_info[tot].song_name=song['songName'] song_info[tot].belong='qianqian' song_info[tot].lrk_api=song['lrcLink'] print(tot, song_info[tot].song_name, '--------歌手:', song_info[tot].artist_name) tot+=1 return tot def qianqian_spider(): print('------------introduction-------------------') print('---------------程序僅供學習交流-------------') print('因涉及到vip音樂下載請不要討論版權問題\n本程序音樂來源--音樂') print('輸入關鍵字可以查找,之后再輸入編號即可下載 None則代表無版權') # print('flag:1:只在酷我音樂中尋找,2:只在qq音樂中尋找 否則同時尋找') print('下載可能比較慢防封ip|暫不知道音質是啥(默認?)') print('--------------------------------------------') #key_word = input(' 輸入關鍵字\n ') key_word=input() page = 0 global song_info song_info = [Song_info() for i in range(10000)] global tot # try: while 1: page += 1 qianqian_song_list = get_qianqian_song_list(key_word, page) tot = 1 time.sleep(0.5) tot=get_song_info_from_qianqian(song_info,tot,qianqian_song_list) # 重復選擇下載歌曲並下載 while (1): download_song = input('輸入要下載的一首歌編號|輸入pass:加載一頁|exit: 退出程序|return:返回搜索關鍵詞\n').strip() if download_song == 'exit': return 0 if download_song == 'return': os.system('cls') return 1 if download_song == 'pass': os.system('cls') break else: download_song = int(download_song) song_name = song_info[download_song].song_name song_nameid = song_info[download_song].song_nameid song_artist = song_info[download_song].artist_name song_api=song_info[download_song].song_api #song_lrk_api = song_info[download_song].lrk_api print(song_name, song_artist, '正在下載') if song_info[download_song].belong == 'qianqian': print('------正在下載' + song_name + '-------') #song_api=get_qianqian_song_api(song_nameid) qianqian_download_mp3(song_name, song_artist, song_api) #download_qianqian_song_lrk(song_name, song_artist, song_lrkid) # except: # print('已經到最后一頁') if __name__=='__main__': qianqian_spider()
總的來說思路都一樣,見招拆招
酷我音樂|親測能用
思路都差不多...
1 下載一首歌
2 找到歌的id
3 找到所有歌的id
4 進入一首歌的頁面
5 下載
6 改變歌手
7 改變頁碼
先放一首歌發現有一個url?文件進入發現里面就是歌曲的url即可下載url長這樣http://www.kuwo.cn/urlformat=mp3&rid=76323299&response=url&type=convert_url3&br=128kmp3&from=web&t=1583462447941&reqId=e2c09e60-5f53-11ea-9a8c-a5d0d057abd1
但是不知道為什么可以不用改動reqid坑我半天直接刪掉都行 吐血
多找幾個能放的歌發現只有rid和reqId改變。這就可以合成歌曲下載地址
然后再搜索歌手,翻頁(這里你會發現翻頁上方的搜索碼不會變化,應該被隱藏了?)可以發現出來一個song_list里面有所有歌的rid,name等data(翻頁真時有驚喜)
然后因為不能直接從頁面獲得搜索url的變化規律所有點擊搜索頁面點擊搜索來抓一個search?的包。可以發現里面的url只有rid和reqId變化,所以只用改rid即可進入單個歌曲的頁面然后再根據上面的即可下載歌曲
盲猜改變歌手,頁面 仍有用
完整代碼
import requests import pprint import os import re import selenium import threading import sys import time class Song_info(object): def __init__(self): self.name='' self.song_nameid='' self.atrist_name='' self.belong='' def get_kuwo_song_list(key_word,page): ''' 得到關鍵字和page的歌單 :param key_word: :param page: :return: ''' #url='https://y.qq.com/portal/search.html url='http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key='+key_word+'&pn='+str(page)+'&rn=30' header={'Referer': 'http://www.kuwo.cn/search/list?key=%E5%91%A8%E6%9D%B0%E4%BC%A6', 'csrf': '7OUIGZGNE07', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', 'cookie':'_ga=GA1.2.816678460.1583305531; _gid=GA1.2.1330734898.1583412010; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1583412949,1583413217,1583413235,1583413437; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1583419987; kw_token=7OUIGZGNE07'} res=requests.get(url,headers=header) res.encoding=res.apparent_encoding html=res.json() song_list=html['data']['list'] return song_list def kuwo_down_load(song_name,song_api): ''' 下載酷我音樂 :param song_name: :param song_api: :return: ''' html=requests.get(song_api).content with open(song_name+'.mp3','wb') as f: f.write(html) path=os.getcwd() print(song_name+' 成功下載到'+path) time.sleep(1.5) return def get_kuwo_song_api(song_nameid,song_keyid): ''' 獲得kuwosong的下載地址 :param song_nameid: :param song_keyid: :return: ''' url='http://www.kuwo.cn/url?format=mp3&rid='+str(song_nameid)+'&response=url&type=convert_url3&br=128kmp3&from=web&t=1583424526196' # 1 這里很奇怪reqID為什么可以不用管 不然我早就弄好了 # 2 不能直接進preview里然后用里面的url格式來套不然會403 header={'Cookie':'ga=GA1.2.816678460.1583305531; _gid=GA1.2.1330734898.1583412010; _gat=1; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1583412949,1583413217,1583413235,1583413437; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1583413437; kw_token=3PV9YR4C19D', 'csrf':'3PV9YR4C19D', 'Referer':'http://www.kuwo.cn/play_detail/324244', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36' }#當前頁面的標頭 html=requests.get(url,headers=header).json() song_api=html['url'] #print(song_api) return song_api def get_song_info_from_kuwo(song_info,tot,kuwo_song_list): ''' 從歌單得到每一首歌的數據 :param tot: :param kuwo_song_list: :return: ''' for song in kuwo_song_list: song_info[tot].name = song['name'] song_info[tot].song_nameid = song['rid'] song_info[tot].atrist_name = song['artist'] song_info[tot].song_keyid='' song_info[tot].belong = 'kuwo' print(tot, song_info[tot].name, '--------歌手:', song_info[tot].atrist_name) tot += 1 return tot def kuwo_spider(): print('-----------------introduction---------------') print('---------------程序僅供學習交流-------------') print('因涉及到vip音樂下載請不要討論版權問題\n本程序音樂來源--酷我音樂') print('輸入歌手|歌曲名稱可以查找,之后再輸入編號即可下載')print('暫不知道音質是啥(默認?)') print('--------------------------------------------') key_word=input(' 輸入關鍵字\n ') page=0 global song_info song_info=[Song_info() for i in range(10000)] global tot try: while 1: page+=1 kuwo_song_list=get_kuwo_song_list(key_word,page) tot=1 tot=get_song_info_from_kuwo(tot,kuwo_song_list) #重復選擇下載歌曲並下載 while(1): download_song=input('輸入要下載的一首歌編號 輸入pass加載一頁 exit 退出程序\n') if download_song=='exit': return if download_song=='pass': break else: download_song=int(download_song) song_name=song_info[download_song].name song_nameid=song_info[download_song].song_nameid song_keyid=song_info[download_song].song_keyid song_artist=song_info[download_song].atrist_name print(song_name, song_artist,'開始下載') if song_info[download_song].belong=='kuwo': print('------正在下載' + song_name + '-------') song_api=get_kuwo_song_api(song_nameid,song_keyid) kuwo_down_load(song_name,song_api) except: print('已經到最后一頁') if __name__=='__main__': kuwo_spider() time.sleep(1)
之后pyinstaller打包一下即可
沒懂?下篇 圖解 更詳細
有用點個推薦吧