利用python语言下载网易云音乐单曲和歌单

程序源代码如下:

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import md5
import base64
import urllib2
import urllib
import json
import random
import os
import sys
import string

#string.replace(u'xa0', u' ')

reload(sys)
sys.setdefaultencoding('utf-8')

#设置cookie
cookie_opener = urllib2.build_opener()
cookie_opener.addheaders.append(('Cookie', 'appver=2.0.2'))
cookie_opener.addheaders.append(('Referer', 'http://music.163.com'))
urllib2.install_opener(cookie_opener)

#加密
#def encrypted_id(id):
#    byte1 = bytearray('3go8&$8*3*3h0k(2)2')
#    byte2 = bytearray(id)
#    byte1_len = len(byte1)
#    for i in xrange(len(byte2)):
#        byte2[i] = byte2[i]^byte1[i%byte1_len]
#    m = md5.new()
#    m.update(byte2)
#    result = m.digest().encode('base64')[:-1]
#    result = result.replace('/', '_')
#    result = result.replace('+', '-')
#    return result
#
#根据歌手名搜索歌手,获取歌手的信息
def search_artist_by_name(name):
    search_url = 'http://music.163.com/api/search/get'
    params = {
            's': name,
            'type': 100,#100是搜索歌手
            'offset': 0,
            'sub': 'false',
            'limit': 10
    }
    params = urllib.urlencode(params)
    resp = urllib2.urlopen(search_url, params)
    artists = json.loads(resp.read())
    if artists['code'] == 200 and artists['result']['artistCount'] > 0:
        return artists['result']['artists'][0]
    else:
        return None

#根据歌手名搜索专辑,获取歌手的专辑的信息
def search_album_by_name(name):
    search_url = 'http://music.163.com/api/search/get'
    params = {
            's': name,
            'type': 10,#10是搜索专辑
            'offset': 0,
            'sub': 'false',
            'limit': 20
    }
    params = urllib.urlencode(params)
    resp = urllib2.urlopen(search_url, params)
    resp_js = json.loads(resp.read())
    if resp_js['code'] == 200 and resp_js['result']['albumCount'] > 0:
        result = resp_js['result']
        album_id = 0
        if result['albumCount'] > 1:
            for i in xrange(len(result['albums'])):
                album = result['albums'][i]
                #列出歌手名、专辑名
                print '[%2d]artist:%stalbum:%s' % (i+1, album['artist']['name'], album['name'])
            #个人选择专辑
            select_i = int(raw_input('Select One:'))
            if select_i < 1 or select_i > len(result['albums']):
                print '错误选择'.encode('gbk')
                return None
            else:
                album_id = select_i - 1
                return result['albums'][album_id]#返回专辑信息
    else:
        return None


#根据歌曲名搜索歌曲,获取歌曲的信息
def search_song_by_name(name):
    search_url = 'http://music.163.com/api/search/get'
    params = {
            's': name,
            'type': 1,#搜索单曲
            'offset': 0,
            'sub': 'false',
            'limit': 30
    }
    params = urllib.urlencode(params)
    resp = urllib2.urlopen(search_url, params)
    resp_js = json.loads(resp.read())
    if resp_js['code'] == 200 and resp_js['result']['songCount'] > 0:
        result = resp_js['result']
        song_id = result['songs'][0]['id']
        if result['songCount'] > 1:
            for i in xrange(len(result['songs'])):
                song = result['songs'][i]
                #打印歌曲名、歌手名、专辑名
                #index_str = '['+str(i+1)+']'+'song:'+song['name']+"t"+'artist:'+song['artists'][0]['name']+"t"+'album:'+ song['album']['name']
                try:
                    print "[%2d]--%s---%s---%s" % (i+1,song['name'].encode('gbk'),song['artists'][0]['name'].encode('gbk'),song['album']['name'].encode('gbk'))
                except UnicodeEncodeError,e:
                    print "[%2d]--%s---%s---%s" % (i+1,song['name'],song['artists'][0]['name'],song['album']['name'])
                #print index_str
                #print '[%2d]song:%startist:%stalbum:%s' % (i+1,song['name'], song['artists'][0]['name'], song['album']['name'])
            #选择一首歌曲
            select_i = int(raw_input("选择一首(输号码):".encode('gbk')))
            if select_i < 1 or select_i > len(result['songs']):
                print '错误选择'.encode('gbk')
                return None
            else:
                song_id = result['songs'][select_i-1]['id']
                #由歌曲的id查询歌曲的信息(mp3链接)
                detail_url = 'http://music.163.com/api/song/detail?ids=[%d]' % song_id
                resp = urllib2.urlopen(detail_url)
                song_js = json.loads(resp.read())
                return song_js['songs'][0]#返回歌曲的信息,包括MP3链接
    else:
        return None

#根据歌手获取歌手的专辑
#def get_artist_albums(artist):
#    albums = []
#    offset = 0
#    while True:
#        url = 'http://music.163.com/api/artist/albums/%d?offset=%d&limit=50' % (artist['id'], offset)
#        resp = urllib2.urlopen(url)
#        tmp_albums = json.loads(resp.read())
#        albums.extend(tmp_albums['hotAlbums'])
#        if tmp_albums['more'] == True:
#            offset += 50
#        else:
#            break
#    return albums

#根据专辑获取专辑的歌曲
#def get_album_songs(album):
#    url = 'http://music.163.com/api/album/%d/' % album['id']
#    resp = urllib2.urlopen(url)
#    songs = json.loads(resp.read())
#    return songs['album']['songs']

#将id对应歌曲下载到硬盘
def save_song_to_disk(song, folder):
    name = song['name']
    fpath = os.path.join(folder, name+'.mp3')
    if os.path.exists(fpath):
        return None


    url = song['mp3Url']
    #print '%st%s' % (url, name)
    #return
    print '正在下载---'.encode('gbk'),song['name'].encode('gbk')
    resp = urllib2.urlopen(url)
    data = resp.read()
    f = open(fpath, 'wb')
    f.write(data)
    f.close()

#根据歌名下载歌曲
def download_song_by_search(name, folder='.'):
    song = search_song_by_name(name)
    if not song:
        print '没找到---'.encode('gbk'),name
        return None

    if not os.path.exists(folder):
        os.makedirs(folder)
    save_song_to_disk(song, folder)

#获取歌单
def search_playlist_by_name(name):
    search_url = 'http://music.163.com/api/search/get'
    params = {
            's': name,
            'type': 1000,#1000是搜索歌单
            'offset': 0,
            'sub': 'false',
            'limit': 30
    }
    params = urllib.urlencode(params)
    resp = urllib2.urlopen(search_url, params)
    resp_js = json.loads(resp.read())
    if resp_js['code'] == 200 and resp_js['result']['playlistCount'] > 0:
        result = resp_js['result']
        playlist_id = 0
        if result['playlistCount'] > 1:
            for i in xrange(len(result['playlists'])):
                playlist = result['playlists'][i]
                #列出歌手名、专辑名
                try:
                    print '[%2d]playlist:%s' %(i+1,playlist['name'].encode('gbk'))
                except UnicodeEncodeError,e:
                    print '[%2d]playlist:%s' %(i+1,playlist['name'])
            #个人选择专辑
            select_i = raw_input("选择一个歌单(输号码):".encode('gbk'))
            select_i = int(select_i)
            if select_i < 1 or select_i > len(result['playlists']):
                print '错误选择'.encode('gbk')
                return None
            else:
                playlist_id = select_i - 1
                return result['playlists'][playlist_id]#返回歌单信息
    else:
        return None
#获取歌单中的歌曲的信息
def get_playlist_songs(playlist):
    url = 'http://music.163.com/api/playlist/detail?id=%d' % playlist['id']
    resp = urllib2.urlopen(url)
    songs = json.loads(resp.read())
    return songs['result']['tracks']#返回歌曲信息

#根据歌单下载
def download_playlist_by_search(name,folder='.'):
    playlist = search_playlist_by_name(name)
    if not playlist:
        print "没找到---".encode('gbk'),name
        return None
    name = playlist['name']
    folder = os.path.join(folder,name)

    if not os.path.exists(folder):
        os.makedirs(folder)

    songs = get_playlist_songs(playlist)
    for song in songs:
        save_song_to_disk(song,folder)



#根据专辑名下载专辑
#def download_album_by_search(name, folder='.'):
#    album = search_album_by_name(name)
#    if not album:
#        print 'Not found ' + name
#        return
#    
#    name = album['name']
#    folder = os.path.join(folder, name)
#
#    if not os.path.exists(folder):
#        os.makedirs(folder)
#
#    songs = get_album_songs(album)
#    for song in songs:
#        save_song_to_disk(song, folder)

#if __name__ == '__main__':
#    if len(sys.argv) < 3:
#        sys.exit(0)
#    download_playlist_by_search(sys.argv[1], sys.argv[2])
if __name__ == '__main__':

    while True:
        print '''**************************************************************************
        ##本程序可以根据歌曲名下载单曲,也可以下载歌单(网易的专辑没API)##
                   输入1,则进入下载单曲功能。
                   输入2,则进入下载歌单功能。
                   输入3,则退出程序。'''.encode('gbk')

        sel = raw_input('请输入你的选择:'.encode('gbk'))
        sel = int(sel)
        if sel == 1:
            print '单曲下载功能(输入歌曲名即可下载)'.encode('gbk')
            name = raw_input("输入需要下载的歌曲名:".encode('gbk'))
            download_song_by_search(name,folder="d://song")
        elif sel == 2:
            print '歌单下载功能(可下载歌单内所有歌曲)'.encode('gbk')
            name = raw_input('输入需要下载的歌单名:'.encode('gbk'))
            #name = name.encode('gbk')
            download_playlist_by_search(name,folder='d://song')
        elif sel == 3:
            break
            print '已退出程序'.encode('gbk')
        else:
            print "输入错误,请重试".encode('gbk')

Categories: Python, 爬虫, 网易云音乐

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值