python爬音乐网站_python爬虫-爬取高逼格音乐网站《落网》

关于

落网,一个高逼格的音乐网站,是很多文艺青年经常逛的网站。经常下载落网音乐到本地,一首一首的下载十分的痛苦。最近刚好在学习python爬虫的东西,刚好把落网音乐的爬取当做一个练习项目来实践(IT从业者的好处~)。

准备

工具 :python 2.7,PyCharm

类库:urllib2、BeautifulSoup、time、re、sys

分析

要想下载落网的音乐,首先要获取每首音乐的url,通过chrome浏览器的开发者工具(F12)查看网页的源代码可以看到图片的URL,没有音频的URL,如图

image

但是,我们发现点击每首歌曲的时候,network都会一个音频的请求,如图

image

那么很显然,这个就是我们需要的下载URL地址了。通过分析http://mp3-cdn2.luoo.net/low/luoo/radio924/02.mp3这个地址,我可以知道前面部分http://mp3-cdn2.luoo.net/low/luoo/是固定的地址,后面的radio924/02.mp3中924是每个期刊的期刊号,其中02是每个期刊下面的第几首歌。要想获取同类型期刊(比如rock),URL为http://www.luoo.net/music/rock,首先我们要获取每个期刊的期刊号于期刊URL的对应关系,通过抓取HTML源码来获得,如图

image.png

代码如下:

#获取每个期刊URL与频道的对应关系,存放在一个dict中

def getReation(self, pageIndex):

soup = self.getPage(pageIndex, '')

vols = {}

pattern = re.compile('[0-9]+') //正则匹配获取HTML源码中的期刊号

if not soup:

return None

vol_lists = soup.find_all('div', class_='meta')

for vol in vol_lists:

vol1 = re.search(pattern, str(vol.a.get_text())).group()

vols[vol1.strip()] = vol.a['href']

return vols

然后根据上面的对应关心来获取每首歌的信息,同样存放在一个dict中,以songName为key,以URL为value,如下。

#获取每首歌的名称和url

def getSongInfo(self, vols):

songInfos = {}

for vol in vols.keys():

url = vols[vol]

soup = self.getPage(0, url)

total = len(soup.find_all('li', class_='track-item'))

songNames = soup.find_all('a', class_='trackname')

for i in range(1, total+1):

songName = self.delSongName(songNames[i - 1].get_text())

if i < 10: //对前面【1-9】首的URL进行格式化。

songURL = self.music_url + 'radio' + str(vol).lstrip('0') + '/0' + str(i) + '.mp3'

else:

songURL = self.music_url + 'radio' + str(vol).lstrip('0') + '/' + str(i) + '.mp3'

songInfos[songName] = songURL

return songInfos

获取到每首歌的信息后,然后我们就可以正式的进行下载了(哈哈,终于到正题了~),如下

def downloadSong(self):

totalPage = self.getTotalPage() //首先获取该类型期刊的总的页数

for pageIndex in range(1, int(totalPage)+1):

vols = self.getReation(pageIndex) //获取每一页的期刊号与URL的对应关系

songInfos = self.getSongInfo(vols) //获取歌曲信息name和URL

for songName, songURL in songInfos.items():

time.sleep(5)

print('%s 正在下载中。。。' %(songName))

try:

data = urllib2.urlopen(songURL).read()

except urllib2.URLError:

print("######链接不存在,继续下载下一首########")

with open (('D:\\test\\song\\%s.mp3' %(songName)).decode('utf-8'), 'wb') as f:

f.write(data)

总结

到这边,基本上,对爬取每个类期刊下面的歌曲有了一个整体的思路,大家可以根据这些来实现自己的爬虫额。

下面给出本人的实现代码,给大家一个参考。

#!-*- coding: utf-8 -*-

import urllib2,urllib

from bs4 import BeautifulSoup

import re

import time

import sys

reload(sys)

sys.setdefaultencoding( "utf-8" )

class DownloadSong(object):

def __init__(self,base_url):

self.url = base_url

self.music_url = 'http://mp3-cdn2.luoo.net/low/luoo/'

self.pageIndex = 1

self.headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'

}

#获取页面的源码

def getPage(self, index, vol_url):

if index != 0:

url = self.url + '?p=' + str(index)

else:

url = vol_url

try:

request = urllib2.Request(url, headers=self.headers)

response = urllib2.urlopen(request).read()

soup = BeautifulSoup(response, 'html.parser')

return soup

except urllib2.URLError, e:

if hasattr(e, 'reason'):

print(u'链接失败,失败原因', e.reason)

return None

#获取总页面数

def getTotalPage(self):

soup = self.getPage(self.pageIndex, '')

if not soup:

return None

totalPage = soup.find_all('a', class_='page')[-1].get_text().strip()

return totalPage

#处理歌曲的名称

def delSongName(self, songName):

return songName.split('.')[1].lstrip().encode('utf-8')

#获取每个期刊URL与频道的对应关系

def getReation(self, pageIndex):

soup = self.getPage(pageIndex, '')

vols = {}

pattern = re.compile('[0-9]+')

if not soup:

return None

vol_lists = soup.find_all('div', class_='meta')

for vol in vol_lists:

vol1 = re.search(pattern, str(vol.a.get_text())).group()

vols[vol1.strip()] = vol.a['href']

return vols

#获取每首歌的名称和url

def getSongInfo(self, vols):

songInfos = {}

for vol in vols.keys():

url = vols[vol]

soup = self.getPage(0, url)

total = len(soup.find_all('li', class_='track-item'))

songNames = soup.find_all('a', class_='trackname')

for i in range(1, total+1):

songName = self.delSongName(songNames[i - 1].get_text())

if i < 10:

songURL = self.music_url + 'radio' + str(vol).lstrip('0') + '/0' + str(i) + '.mp3'

else:

songURL = self.music_url + 'radio' + str(vol).lstrip('0') + '/' + str(i) + '.mp3'

songInfos[songName] = songURL

return songInfos

#下载歌曲

def downloadSong(self):

totalPage = self.getTotalPage()

for pageIndex in range(1, int(totalPage)+1):

vols = self.getReation(pageIndex)

songInfos = self.getSongInfo(vols)

for songName, songURL in songInfos.items():

time.sleep(5) //适当的减慢下载速度,不要给人家服务器造成压力。

print('%s 正在下载中。。。' %(songName))

try:

data = urllib2.urlopen(songURL).read()

except urllib2.URLError:

print("######链接不存在,继续下载下一首########")

with open (('D:\\test\\song\\%s.mp3' %(songName)).decode('utf-8'), 'wb') as f:

f.write(data)

if __name__ == '__main__':

url = 'http://www.luoo.net/music/classical' //传入古典期刊的url

downloadsong = DownloadSong(url) //生成一个对象

downloadsong.downloadSong() //调用downloadSong方法来正式下载额。

结果如下

image.png

image.png

如果对您有点帮助的话,麻烦您给点个赞,谢谢。

你可能感兴趣的:(python爬音乐网站)