爬取 音乐歌曲(千千,酷我)

Posted cherrypill

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了爬取 音乐歌曲(千千,酷我)相关的知识,希望对你有一定的参考价值。

没有用多线程

1 千千音乐

 

步骤|思路:

 

首先要能爬取一首歌然后再爬取歌单的第一面,最后爬取可选择的页数

 

爬取一首歌首先要找到network里的media 里面如果有东西则可发现这才是这首歌真实播放|下载 地址 然后根据xcode来搜索(倒推)它的下载源比如有 songlink,ting...等类似的文件,进去后preview可以看到歌曲的各种介绍,最后爬进这个下载源获得歌曲下载链接等数据 即可

 

坑点

 

我认为)json文件是像字典一样的所以开头结尾要是{}如果{}前后有东西要先正则除去,之后才能json.loads(xxx)否则会报错说什么不是json格式(这里百度只会叫你该单引号之类的然鹅实际上是上面的问题)

 

如果request.get(url,parama,headers).text=‘‘ .content=b‘‘则说明header要加referer参数(被反爬了?)

 

具体讲解见代码

 
from bs4 import BeautifulSoup
import requests
from selenium import webdriver
import urllib.request
import pprint
import json
import re
‘‘‘
先找mp3到的下载地址在根据xcode寻找到包含这个歌曲的那个歌单 
然后在搜索页面(network第一个)ctrl+f搜索歌曲id
‘‘‘
if __name__==__main__:
    search_api=http://music.taihe.com/search?
    singer_name={"key":林俊杰}
    print(输入歌手名称)
    #singer_name=input()
    #page_number=int(input())

    header = {
        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: E1RjBzZzY1cDRlTmRyWTFtMGN5b0pNM1VTcXQ3aVZTWnJ1fkk2aG94LWRiT1pkRVFBQUFBJCQAAAAAAAAAAAEAAAAOw~ynMTQ2MzUzNTMxNWZibAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ3fvl2d375da0; BAIDUID=10E17A0301BD00EC5B8D0E92CA54188F:FG=1; userid=2818360078; u_id=; u_t=; u_login=1; u_lo=0; BAIDU_SSP_lcr=https://my.oschina.net/zhmlvft/blog/472466?p={{totalPage}}; Hm_lvt_d0ad46e4afeacf34cd12de4c9b553aa6=1583374517,1583387044,1583387159,1583387225; tracesrc=-1%7C%7C-1; __qianqian_pop_tt=6; Hm_lpvt_d0ad46e4afeacf34cd12de4c9b553aa6=1583400033
        , Referer: http://music.taihe.com/song/1137385?pst=sug}


    res=requests.get(search_api,params=singer_name,headers=header)
    #params可以直接自动识别并拼接关键词就不用我们自己拼了
    #得到一个响应
    res.encoding=res.apparent_encoding#自动获取编码形式,万能
    html=res.text
    song_ids=re.findall(r"sid":(d+),&quot,html)
    #print(song_ids)
    #这里直接在源码里面搜其中一个歌的id,不过要先筛选因为会找到很多包含这首歌id的语句
    # 这样就能搜到其他歌了因为其他歌的id肯定也符合这个式子,

    #这个url获得是先播放这首歌在find xcode 可以找到一个得到ting文件这个文件里面有

    url=http://musicapi.taihe.com/v1/restserver/ting?method=baidu.ting.song.playAAC&format=jsonp&callback=jQuery17209677148092769645_1583387566116&songid=1137385&from=web&_=1583387569190
    #找同一歌手两首歌发现上面的url只有song_id改变了故可以猜测。。。
    header={User-Agent:Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 80.0.3987.132Safari / 537.36
        ,Cookie:E1RjBzZzY1cDRlTmRyWTFtMGN5b0pNM1VTcXQ3aVZTWnJ1fkk2aG94LWRiT1pkRVFBQUFBJCQAAAAAAAAAAAEAAAAOw~ynMTQ2MzUzNTMxNWZibAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ3fvl2d375da0;BAIDUID = 10E17A0301BD00EC5B8D0E92CA54188F: FG = 1;userid = 2818360078;u_login = 1;BAIDU_SSP_lcr = https: // my.oschina.net / zhmlvft / blog / 472466?p = {{totalPage}}
        ,Referer:http: // music.taihe.com / song / 1332939
    }

    #现在只需要访问这个网址的showlink|filelink即可下载 这个这么难找的网址感觉一般都有反爬
    # 可以先输出一下res(如果是200说明正常访问)看看返回在判断加不加header
    res=requests.get(url,headers=header)
    element=re.findall(r{.*},res.text)[0]
#正则除去开头那些东西否则不会被识别为json文件
    print(element)
    info=json.loads(element)
    # 要看一下文件时什么格式然后用相应的处理方式
    song_download_api=info[bitrate][show_link]
    song_name=info[songinfo][title]
    print(song_name,song_download_api)
    # with open(‘隔空拥抱.mp3‘,‘wb‘) as f:
    #     f.write(res.content)
    #只有文字才有gbk,utf-8格式
    #text得到的是文本之类的音乐视频如果用text则什么都输出不了,应用content

 

 

这是爬取固定歌手某一首歌,的第一面封装一下再找找页码规律从而可以爬取任意页,盲猜歌手名字改变不会影响什么(但是这样有bug,不能爬没版权的东西)代码只改了开始的开始的url部分

 
from bs4 import BeautifulSoup
import requests
from selenium import webdriver
import urllib.request
import pprint
import json
import re
‘‘‘
没有版权下不了
先找mp3到的下载地址在根据xcode寻找到包含这个歌曲的那个歌单 
然后在搜索页面(network第一个)ctrl+f搜索歌曲id
‘‘‘
def find_songid(singer_name,page):
    search_api = http://music.taihe.com/search/song?s=1&key=+singer_name+&jump=0&start=+str((page-1)*20)+&size=20&third_type=0
    # singer_name=input()
    # page_number=int(input())
    # 这个网站这么好进一般没有反爬
    header = {
        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: E1RjBzZzY1cDRlTmRyWTFtMGN5b0pNM1VTcXQ3aVZTWnJ1fkk2aG94LWRiT1pkRVFBQUFBJCQAAAAAAAAAAAEAAAAOw~ynMTQ2MzUzNTMxNWZibAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ3fvl2d375da0; BAIDUID=10E17A0301BD00EC5B8D0E92CA54188F:FG=1; userid=2818360078; u_id=; u_t=; u_login=1; u_lo=0; BAIDU_SSP_lcr=https://my.oschina.net/zhmlvft/blog/472466?p={{totalPage}}; Hm_lvt_d0ad46e4afeacf34cd12de4c9b553aa6=1583374517,1583387044,1583387159,1583387225; tracesrc=-1%7C%7C-1; __qianqian_pop_tt=6; Hm_lpvt_d0ad46e4afeacf34cd12de4c9b553aa6=1583400033
        , Referer: http://music.taihe.com/song/1137385?pst=sug}
    res = requests.get(search_api, params=singer_name, headers=header)
    # params可以直接自动识别并拼接关键词就不用我们自己拼了
    # 得到一个响应
    res.encoding = res.apparent_encoding  # 自动获取编码形式,万能
    html = res.text
    return html
def find_song_info(id):
    url = http://musicapi.taihe.com/v1/restserver/ting?method=baidu.ting.song.playAAC&format=jsonp&callback=jQuery17209677148092769645_1583387566116&songid= + id + &from=web&_=1583387569190
    # 找同一歌手两首歌发现上面的url只有song_id改变了故可以猜测。。。
    header = {
        User-Agent: Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 80.0.3987.132Safari / 537.36
        ,
        Cookie: E1RjBzZzY1cDRlTmRyWTFtMGN5b0pNM1VTcXQ3aVZTWnJ1fkk2aG94LWRiT1pkRVFBQUFBJCQAAAAAAAAAAAEAAAAOw~ynMTQ2MzUzNTMxNWZibAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ3fvl2d375da0;BAIDUID = 10E17A0301BD00EC5B8D0E92CA54188F: FG = 1;userid = 2818360078;u_login = 1;BAIDU_SSP_lcr = https: // my.oschina.net / zhmlvft / blog / 472466?p = {{totalPage}}
        , Referer: http: // music.taihe.com / song / 1332939
        }
    # 现在只需要访问这个网址的showlink|filelink即可下载 这个这么难找的网址感觉一般都有反爬
    # 可以先输出一下res(如果是200说明正常访问)看看返回在判断加不加header
    res = requests.get(url, headers=header)
    element = re.findall(r{.*}, res.text)[0]
    # 正则除去开头那些东西否则不会被识别为json文件
    info = json.loads(element)
    # 要看一下文件时什么格式然后用相应的处理方式
    song_download_api = info[bitrate][show_link]
    song_name = info[songinfo][title]
    return song_name,song_download_api
def download(name,api):
    mp3=requests.get(api).content
    #print(mp3)
    with open(name+.mp3,wb) as f:
        f.write(mp3)
    print(name+ 下载完成 )
    return
if __name__==__main__:
    pages=int(input(要爬取前多少页))
    singer_name = input(输入要爬的歌手名字)
    for page in range(1,pages+1):
        html=find_songid(singer_name,page)
        song_ids=re.findall(r"sid":(d+),&quot,html)
        print(song_ids)
        #这里直接在源码里面搜其中一个歌的id,不过要先筛选因为会找到很多包含这首歌id的语句
        # 这样就能搜到其他歌了因为其他歌的id肯定也符合这个式子,

        #这个url获得是先播放这首歌在find xcode 可以找到一个得到ting文件这个文件里面有
        for i in song_ids:
            song_name,song_download_api=find_song_info(i)
            download(song_name,song_download_api)
            # with open(‘隔空拥抱.mp3‘,‘wb‘) as f:
            #     f.write(res.content)
            #只有文字才有gbk,utf-8格式
            #text得到的是文本之类的音乐视频如果用text则什么都输出不了,应用content

2 酷我音乐:

思路:

1 下载一首歌 2 找到歌的id 3 找到所有歌的id 4 进入一首歌的页面 5 下载

 

6 改变歌手 7 改变页码

 

先放一首歌发现有一个url?文件进入发现里面就是歌曲的url即可下载url长这样

 

但是不知道为什么可以不用改动reqid坑我半天

 

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

 

多找几个能放的歌发现只有rid和reqId改变。这就可以合成歌曲下载地址

 

然后再搜索歌手,翻页(这里你会发现翻页上方的搜索码不会变化,应该被隐藏了?)可以发现出来一个song_list里面有所有歌的rid,name等data(翻页真时有惊喜)

 

然后因为不能直接从页面获得搜索url的变化规律所有点击搜索页面点击搜索来抓一个search?的包。可以发现里面的url只有rid和reqId变化,所以只用改rid即可进入单个歌曲的页面然后再根据上面的即可下载歌曲

 

盲猜改变歌手,页面 仍有用即可得到完整代码 初级版代码,不要管他

 
import requests
import pprint
import os
import re
import selenium
from bs4 import BeautifulSoup
‘‘‘
只能精确搜索(即你在网页上搜索出什么就是什么没有选择余地)
‘‘‘
def get_song_list(singer_name,name,page):
    #url=‘https://y.qq.com/portal/search.html#page=‘+str(page)+‘&searchid=1&remoteplace=txt.yqq.top&t=song&w=‘+singer_name
    url=http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key=+singer_name+name+&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()
    #regular=r""
    #html=re.findall(regular,html)
    song_list=html[data][list]
    return song_list
def down_load(song_name,song_api):
    html=requests.get(song_api).content
    with open(song_name+.mp3,wb) as f:
        f.write(html)
    print(song_name+  下载完成)

def get_song_api(song_name,rid):
    url=http://www.kuwo.cn/url?format=mp3&rid=+str(rid)+&response=url&type=convert_url3&br=128kmp3&from=web&t=1583424526196&reqId=97a1b160-5efb-11ea-8199-53e1afcdfde3
    # 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)
    #down_load(song_name,song_api)
    return

if __name__==__main__:
    singer_name=input( 输入歌手全名
  )
    name=input( 输入歌曲名称
  )
    #pages=int(input(‘输入查看页数 最大10000(否则默认查看第一页)‘))
    pages=2
    for page in range(1,pages+1):
        song_list=get_song_list(singer_name,name,page)
        tot=1
        for song in song_list:
            song_name=(song[name])
            song_rid=song[rid]
            song_artist=song[artist]
            get_song_api(song_name,song_rid)
            print(tot,song_name, 歌手:,song_artist)
            tot+=1
        download_song=input(输入要下载的编号 输入pass跳过这一页)
        if download_song==pass:
            pass
        else:
            download_song=int(download_song)
            song_name=song_list[download_song-1][name]
            song_rid=song_list[download_song-1][rid]
            song_artist=song_list[download_song-1][artist]
            #down_load(song_name,song_rid)
            print(song_name,song_artist)
            exit()

 

 

下面是改进后的代码成品

 
import requests
import pprint
import os
import re
import selenium
import urllib.request
from bs4 import BeautifulSoup
import time
‘‘‘
不能自动获取总页面数量
‘‘‘
def get_song_list(singer_name,name,page):
#url=‘https://y.qq.com/portal/search.html
url=‘http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key=‘+singer_name+name+‘&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 down_load(song_name,song_api):
html=requests.get(song_api).content
with open(song_name+‘.mp3‘,‘wb‘) as f:
f.write(html)
print(song_name+‘ 下载完成‘)
time.sleep(1.5)

def get_song_api(song_name,rid):
url=‘http://www.kuwo.cn/url?format=mp3&rid=‘+str(rid)+‘&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 kuwo_spider():
print(‘-----------------introduction---------------‘)
print(‘因涉及到vip音乐下载请不要讨论版权问题 本程序音乐来源--酷我音乐‘)
print(‘输入歌手|歌曲名称可以查找,之后再输入编号即可下载‘)
print(‘flag输入为1代表当前页全部下载,否则正常输入编号下载‘)
print(‘暂不支持同时下载几首歌‘)
print(‘--------------------------------------------‘)
singer_name=input(‘ 输入歌手全名 ‘)
name=input(‘ 输入歌曲名称 ‘)
global flag
flag=input(‘输入flag ‘)
page=0
try:
while 1:
page+=1
song_list=get_song_list(singer_name,name,page)
tot=1
for song in song_list:
song_name=(song[‘name‘])
song_rid=song[‘rid‘]
song_artist=song[‘artist‘]
if flag !=‘1‘:
print(tot, song_name,‘--------歌手:‘,song_artist)
print()
song_api=get_song_api(song_name,song_rid)
if flag == ‘1‘:
down_load(song_name, song_api)
# 加了这句就是下载全部歌曲
tot+=1
if flag==‘1‘:
print(‘输入pass下载下一页 exit 退出‘)
download_song=input()
if download_song == ‘exit‘:
return
if download_song == ‘pass‘:
pass
else:
download_song=input(‘输入要下载的一首歌编号 输入pass加载一页 exit 退出 ‘)
if download_song==‘exit‘:
return
if download_song==‘pass‘:
pass
else:
download_song=int(download_song)
song_name=song_list[download_song-1][‘name‘]
song_rid=song_list[download_song-1][‘rid‘]
song_artist=song_list[download_song-1][‘artist‘]
print(song_name, song_artist,‘开始下载‘)
song_api=get_song_api(song_name,song_rid)
down_load(song_name,song_api)
return
except:
print(‘已经到最后一页‘)
if __name__==‘__main__‘:
kuwo_spider()
print(‘感谢使用‘)
print(‘源码请关注我的博客 https://misaka.design.blog/2020/03/06/%e7%88%ac%e5%8f%96-%e9%9f%b3%e4%b9%90%e6%ad%8c%e6%9b%b2/‘)

 

以上是关于爬取 音乐歌曲(千千,酷我)的主要内容,如果未能解决你的问题,请参考以下文章

为啥酷我音乐免费听不了

you-get下载酷我音乐付费歌曲

获取酷我音乐歌曲URL地址

Python的requests爬取酷我音乐的一些坑(报错友好错误界面csrf动态网页)

Python 使用tkinter开发exe程序,开发酷我音乐免费下载软件

Python爬虫 | 爬取酷我音乐并下载——requests库之GET方法(免费听歌!!!)