简介:
利用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)
界面大概是这个样子,还可以去添加更多的功能,界面还可以去美化,后续会继续更新。
后续界面更新,资源可下载,到连接(音乐播放器)。