python爬虫(20)获取酷我音乐排行榜榜单作品
获取酷我音乐榜单歌曲
共分为三步
第一步,在榜单主页,获取各个榜单的名字以及bangid
酷我榜单主页:http://www.kuwo.cn/bang/index
从这里可以看到有三类榜单,全球榜,分类榜还有特色榜,每一个分类榜单再包含几个榜单
然后我们就可以使用F12工具查看一下网页元素
我们需要获得的元素是榜单名字,以及bangid,这两个元素是关键
因为我们可以在网络视图中看到,当点击一个榜单的时候,它的请求如下:
http://www.kuwo.cn/bang/content?name=酷我热歌榜&bangId=16
也就是说格式是固定的 http://www.kuwo.cn/bang/content?name={name}&bangId={bandid}
因此我们需要这个榜单名字和bangid
根据审查元素,这些榜单名字都位于{div}节点下 class = leftNav中的{li}元素中,
其中名字可以根据{li}节点的text文本或者其中的属性 data-name 获得,bangid 可以根据{li}属性的data-bangid获得
代码如下:
def getRankTypeNamelist():
headers ={
'Accept': '*/*',
'Accept-Encoding': 'identity;q=1, *;q=0',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'Host': 'www.kuwo.cn',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',
'Range': 'bytes=0-'
}
url='http://www.kuwo.cn/bang/index'
html=s.get(url).content.decode('utf-8')
doc=pq(html)
Ranknamelist=doc("div.leftNav")('li')
for index,sing in enumerate(Ranknamelist.items()):
ranktype,bangid=sing.text(),sing.attr('data-bangid')
print(ranktype,bangid)
第二步,根据榜单名字以及bangid组装url,得到榜单歌曲列表
榜单的新的url组装方式如下:
url='http://www.kuwo.cn/bang/content?name=%s&bangId=%s' % (urllib.parse.quote(rankType),bangid)
这个页面单独打开像下面一样
从这里我们可以得到排行顺序,歌曲的名字,演唱者
但是重要的还是歌曲的url地址
歌曲的url以及名字应该是
div->class=name ->a.href div->class=name ->a.text()
def getRanklist(rankType='酷我热歌榜',bangid='16'):
headers ={
'Accept': '*/*',
'Accept-Encoding': 'identity;q=1, *;q=0',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'Host': 'www.kuwo.cn',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',
'Range': 'bytes=0-'
}
url='http://www.kuwo.cn/bang/content?name=%s&bangId=%s' % (urllib.parse.quote(rankType),bangid)
html=s.get(url,headers=headers).content.decode('utf-8')
doc=pq(html)
singlist=doc('div.name')
print(len(singlist))
Ranklist=[]
for index,sing in enumerate(singlist.items()):
songname=sing('a').text()
songplayurl=sing('a').attr('href')
songid=songplayurl.split('?')[0].split('/')[-1]
rank=index+1
songinfoUrl=getSongurl(songid)
print(songplayurl,songid,rank)
songid是在songurl里面的,比如沙漠骆驼的播放地址为:"http://www.kuwo.cn/yinyue/25966867?catalog=yueku2016"
然后它的ID就是25966867
songid=songplayurl.split('?')[0].split('/')[-1]
第三步,根据每个歌曲的ID,组装新的歌曲信息页面,得到真正的歌曲url
每首歌曲的信息页面,通过songid来组装
def getSongurl(songid):
base='http://player.kuwo.cn/webmusic/st/getNewMuiseByRid?rid=MUSIC_'
return base+songid
得到的页面大概如下:
这样就能得到具体的播放文件了
完整代码如下:
import requests
import re
import urllib.parse
from pyquery import PyQuery as pq
import webbrowser as wb
import time
import json
import redis
import urllib.request
s = requests.session()
def getRanklist(rankType='酷我热歌榜',bangid='16'):
headers ={
'Accept': '*/*',
'Accept-Encoding': 'identity;q=1, *;q=0',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'Host': 'www.kuwo.cn',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',
'Range': 'bytes=0-'
}
url='http://www.kuwo.cn/bang/content?name=%s&bangId=%s' % (urllib.parse.quote(rankType),bangid)
html=s.get(url,headers=headers).content.decode('utf-8')
doc=pq(html)
singlist=doc('div.name')
print(len(singlist))
Ranklist=[]
for index,sing in enumerate(singlist.items()):
songname=sing('a').text()
songplayurl=sing('a').attr('href')
songid=songplayurl.split('?')[0].split('/')[-1]
rank=index+1
songinfoUrl=getSongurl(songid)
print(songplayurl,songid,rank)
songobj = {
"rank":rank,
"songname":songname,
"songid":songid,
"songinfoUrl":songinfoUrl,
"songplayurl":songplayurl,
"exist":0
}
data=getjson(songinfoUrl,songobj)
#data=json.dumps(data) #json.loads()与json.dumps()可以字典数据和字符串数据的互换
Ranklist.append(data)
#Ranklist=json.dumps(Ranklist)
return Ranklist
def getSongurl(songid):
base='http://player.kuwo.cn/webmusic/st/getNewMuiseByRid?rid=MUSIC_'
return base+songid
def getjson(songinfoUrl,songobj):
html=s.get(songinfoUrl).content.decode('utf-8')
songname=songobj['songname']
songplayurl=songobj['songplayurl']
if not html:
print ('页面错误')
return songobj
doc=pq(html)
singer=doc('singer').text()
if(singer):
path=doc('path').text()
mp3path=doc('mp3path').text()
mp3dl=doc('mp3dl').text()
aacpath=doc('aacpath').text()
aacdl=doc('aacdl').text()
#print(path)
wmapath='http://'+mp3dl+'/resource/'+path
mp3path='http://'+mp3dl+'/resource/'+mp3path
aacpath='http://'+aacdl+'/resource/'+aacpath
#print(wmapath,mp3path,aacpath)
songobj['singer']=singer
songobj['wmapath']=wmapath
songobj['mp3path']=mp3path
songobj['aacpath']=aacpath
songobj['exist']=1
else:
songobj['exist']=0
print('[%s]不存在,播放页面为[%s],信息页面为[%s]' % (songname,songplayurl,songinfoUrl))
return songobj
def getRankTypeNamelist():
headers ={
'Accept': '*/*',
'Accept-Encoding': 'identity;q=1, *;q=0',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'Host': 'www.kuwo.cn',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',
'Range': 'bytes=0-'
}
url='http://www.kuwo.cn/bang/index'
html=s.get(url).content.decode('utf-8')
doc=pq(html)
Ranknamelist=doc("div.leftNav")('li')
for index,sing in enumerate(Ranknamelist.items()):
ranktype,bangid=sing.text(),sing.attr('data-bangid')
print(ranktype,bangid)
rankdata=getRanklist(ranktype,bangid)
#getRanklist(rankType='iTunes音乐榜',bangid='49')
getRankTypeNamelist()