爬取qq,酷我,千千VIP音樂 上


多線程以后再打吧

 記在開頭:如果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+),&quot', 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+),&quot', 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打包一下即可

沒懂?下篇 圖解 更詳細

有用點個推薦吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM