Python+Web制作音乐播放器

2 篇文章 0 订阅
1 篇文章 0 订阅

简介:

利用Python爬虫根据歌曲名称爬取歌曲的URL、封面图片、歌词
采用了网易云音乐的三个接口:
1.根据歌曲名称来获取歌曲ID和歌曲封面:http://s.music.163.com/search/get/?type=1&s=歌曲名称
2.根据歌曲ID获取获取歌曲URL:https://api.imjad.cn/cloudmusic/?type=song&id=歌曲ID
3.根据歌曲ID获取歌曲的歌词:http://music.163.com/api/song/lyric?id=歌曲ID&lv=1&kv=1&tv=-1

一、web端的构建

web端可以将用户输入的歌曲名称作为GET请求的参数传入后端,后端经过一系列爬取操作将歌曲的URL、歌曲的封面图片、歌曲的歌词反馈给前端,前端将这些数据播放并显示,且能实现歌词的动态滚动。
1.html部分:

<div id="Music">
			<div class="select">
				<input type="text" name="musicName" id="musicName" value="" />
				<!--<input type="button" name="select" id="select" value="搜索" />-->
				<a id="select" href="s?name=" onclick="getMusicName()">搜索</a>
			</div>
			<div id="lyrics">
				<!--<input type="text" name="txtlyrics" id="txtlyrics" value="" />-->
				<textarea id="lrc-container" name="textfield" cols="70" rows="10" >
					$mp3Lrc
				</textarea>
			    <!--<ul id="showLrc" style="overflow: hidden;">
   				</ul>-->
   				<div id="lyric-area">
    				<ul id="showLrc"></ul>
				</div>
			</div>
			<div id="play">
				<audio id="myMusic" src=$mp3url controls autoplay ></audio>
				<input type="button" name="playMusic" id="playMusic" value="暂停" onclick="playPause()" />
			</div>
</div>

2.css部分:

           body{
					margin: 0px;
					height: 0px;
				}
			#Music{
				margin: 0 auto;
				display: block;
				width: 350px;
				height: 600px;
				border: solid 1px red;
				border-radius: 20px;
				margin-top: 30px;
			}
			.select{
				/*border: solid 1px black;*/
				width: 230px;
				height: 30px;
				margin: 0 auto;
				margin-top:60px;
				margin-bottom: 20px;
			}
			#musicName{
				height: 22px;
				width: 150px;
				border-color: red;
				float: left;
			}
			#select{
				display: block;
				float: left;
				text-decoration: none;
				width:50px;
				text-align: center;
				line-height: 30px;
				height: 30px;
				border-radius: 10px;
				border-color: red;
				background-color: red;
				color: white;
				font-size: 15px;
				margin-left: 10px;
			}
			#lyrics{
				/*border:solid 1px black;*/
				width: 300px;
				height: 380px;
				margin: 0 auto;
			}
			#txtlyrics{
				width: 250px;
				height: 340px;
				margin-left: 22px;
				margin-top: 20px;
				text-align: center;
			}
			#play{
				/*border: solid 1px black;*/
				margin:0 auto;
				width: 50px;
				height: 50px;
			}
			#playMusic{
				width:50px ;
				height: 50px;
				border-radius: 35px;
				background-color: red;
				/*border: solid 1px black;*/
				color: white;
				font-size: 16px;
			}	
			#lrc-container{
				width: 290px;
				height: 200px;
				display: none;
			}
			#showLrc{
				line-height: 30px;
    				transition-duration: 600ms;
			}
			#lyric-area {
			    width: 290px;
			    height: 330px;
			    overflow: hidden;
			}
			li{
				list-style: none;
				color: white;
			}
			.currentLrc {
			    color: red;
			    font-size: 20px;
			}
			#myMusic{
				width: 300px;
				margin-left: -125px;
			}	

3.js部分:

<script type="text/javascript">
		var audio = document.getElementById("myMusic");
	    var showLrc = document.getElementById("showLrc");
	    var lis = showLrc.getElementsByTagName("li");
	    var lrcContainer = document.getElementById('lrc-container');
	    var lrcArr = [];//定义一个数组存储歌词和对应的时间
	    var currentlineNum = 0; //当前行
	    var middleLine = 4; //中间行
	    var scroll = -30;//滚动距离(等于行高)
	    
		function playPause()
		{
			if(audio.paused)
			{
				audio.play();
				document.getElementById("playMusic").value="暂停";
			}
			else
			{
				audio.pause();
				document.getElementById("playMusic").value="继续";
			}
		}
		function getMusicName()
		{
			document.getElementById("select").href+=document.getElementById("musicName").value;
		}
		
	    getLrc();
	    
    //获取歌词
    function getLrc() {
        lrcArr = [];
        var lyric = lrcContainer.innerText;
        var theLrc = lyric.split("\n");    // 用换行符拆分获取到的歌词
        showLrc.innerHTML = "";
        for (var i = 0; i < theLrc.length; i++) {
            var t = theLrc[i].substring(theLrc[i].indexOf("[") + 1, theLrc[i].indexOf("]"));
            var time = (t.split(":")[0] * 60 + parseFloat(t.split(":")[1])).toFixed(3);
            if (!isNaN(time)) {
                lrcArr.push({
                    t: time,
                    c: theLrc[i].substring(theLrc[i].indexOf("]") + 1, theLrc[i].length)
                });
            }
        }
        for (var j = 0; j < lrcArr.length; j++) {
            var liObj = document.createElement("li");
            liObj.innerText = lrcArr[j].c;
            showLrc.appendChild(liObj);
        }
    }
    
     audio.ontimeupdate = function () {
     	
     	 var curTime = audio.currentTime; //播放器时间
     	 var durTime = audio.duration;//歌曲总时长
        //一次播完后再次播放
        if (curTime == durTime)
        {
        	currentlineNum = 0;
        }
        if (currentlineNum == 0) {
            showLrc.lastChild.removeAttribute("class");//去掉最后一行的高亮样式
            showLrc.style.transform = "translateY(0)";//回到第一行
            audio.play();
        }
        //歌词同步
        if (currentlineNum < lrcArr.length) {
            if (parseFloat(lrcArr[currentlineNum].t) <= curTime) {
            	lineHigh();
                currentlineNum++;
            }
        }
    };
   //显示当前歌词及文字滚动控制
    function lineHigh() {
        if (currentlineNum > 0) {
            lis[currentlineNum - 1].removeAttribute("class");//去掉上一行的高亮样式
        }
        lis[currentlineNum].className = "currentLrc";//显示当前行
        //文字滚动
        if (currentlineNum > middleLine) {
            showLrc.style.transform = "translateY(" + (currentlineNum - middleLine) * scroll + "px)"; //整体向上滚动一行高度
        }
    }
		
	</script>

注意:在这里我们需要从后台获取三个数据:歌曲的URL(mp3url)、歌曲的封面图片(mp3Img)、歌词(mp3Lrc),所以我们需要在html文件的最上面添加这样一行代码:

$def with(mp3url="https://m7.music.126.net/20200406154523/c1c93846c104084c030ba7c3963534a2/ymusic/7450/e769/e906/ff7f4f5855a184e3a96882286140e546.mp3",mp3Img="http://p1.music.126.net/0mfYXX6qyfsOMBLgvuvEyQ==/109951163576069534.jpg",mp3Lrc="")

二、后端爬取

1.接收前端请求并反馈数据:

import web
from getMusic import getMp3Music

urls = (
    '/','Index',
    '/s','So'
)
app = web.application(urls,globals())
render = web.template.render('MusicDemo')
class Index:
    def GET(self):
        return render.index()

class So:
    def GET(self):
        i=web.input()#获取请求数据
        name=i.get('name')
        mp3Url,mp3Img,mp3Lrc=getMp3Music(name)
        return render.index(mp3Url,mp3Img,mp3Lrc)

if __name__ == '__main__':
    app.run()

2.爬取歌曲信息:

import  requests
import json
import re

#f'https://api.imjad.cn/cloudmusic/?type=song&id=32785674'
def getMp3Music(name):
    """
    :param name:歌曲名称
    :return:歌曲URL,歌曲图片,歌词
    """
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
    }
    url = f'http://s.music.163.com/search/get/?type=1&s={name}'
    res = requests.get(url,headers=headers)
    text = json.loads(res.text)

    try:
        mp3ID = text['result']['songs'][0]['id']
    except Exception as e:
        mp3ID = "485612576"
    try:
        mp3Img = text['result']['songs'][0]['album']['picUrl']
    except Exception as e:
        mp3Img = "http://p1.music.126.net/0mfYXX6qyfsOMBLgvuvEyQ==/109951163576069534.jpg"
    print(mp3Img)

    url1 =f'https://api.imjad.cn/cloudmusic/?type=song&id={mp3ID}'
    res1 = requests.get(url1,headers=headers)
    text1 = json.loads(res1.text)
    try:
        mp3Url = text1['data'][0]['url']
    except Exception as e:
        mp3Url = "https://m7.music.126.net/20200406154523/c1c93846c104084c030ba7c3963534a2/ymusic/7450/e769/e906/ff7f4f5855a184e3a96882286140e546.mp3"
    print(mp3Url)

    url2 = f'http://music.163.com/api/song/lyric?id={mp3ID}&lv=1&kv=1&tv=-1'
    res2 = requests.get(url2,headers=headers)
    text2 = json.loads(res2.text)
    try:
        mp3Lrc = text2['lrc']['lyric']
    except Exception as e:
        mp3Lrc = "无"

    # pat = re.compile(r'\[.*\]')
    # mp3Lrc = re.sub(pat,"",mp3Lrc)
    # mp3Lrc = mp3Lrc.strip()
    print(mp3Lrc)
    return mp3Url,mp3Img,mp3Lrc

# if __name__ == '__main__':
#     text = getMp3Music('海阔天空')
#     print(text)


界面大概是这个样子,还可以去添加更多的功能,界面还可以去美化,后续会继续更新。

完成后的模样
在这里插入图片描述
后续界面更新,资源可下载,到连接(音乐播放器)。
在这里插入图片描述

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值