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

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

scrapy版本的Python + Scrapy爬取高逼格音乐网站《落网》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • 引言 今天分析的是一款小而美的音乐产品,相信对一个资深乐迷或真文艺青年来说,对这一款音乐产品应该不会陌生,它的名字...
    fou7阅读 2,376评论 3 43
  • 背景真的是硬伤啊!继续加油
    瑶姬崇云阅读 335评论 1 8
  • 感悟:在你嫌弃工资低的时候请先算一下公司和自己的损益表,再去说你的创造价值是多少,同样公司在付给你工资的同时公司也...
    临淄茂业DDM黄红阅读 264评论 0 0
  • 每个人丈量幸福的尺子不同,幸福感也就不同。平实是我一直以来感觉最美好的幸福。 小时候,享受着父母带给我们...
    咫尺为邻阅读 264评论 0 1