1. 程式人生 > >python爬蟲(20)獲取酷我音樂排行榜榜單作品

python爬蟲(20)獲取酷我音樂排行榜榜單作品

獲取酷我音樂榜單歌曲

共分為三步

第一步,在榜單主頁,獲取各個榜單的名字以及bangid

從這裡可以看到有三類榜單,全球榜,分類榜還有特色榜,每一個分類榜單再包含幾個榜單

然後我們就可以使用F12工具檢視一下網頁元素

我們需要獲得的元素是榜單名字,以及bangid,這兩個元素是關鍵

因為我們可以在網路檢視中看到,當點選一個榜單的時候,它的請求如下:

因此我們需要這個榜單名字和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()