python音乐相册_python爬虫之爬取网易云音乐的歌曲图片和歌词

0.目录

1.分析页面

2.获取歌曲的id

3.获取歌曲信息

4.获取歌曲图片url

5.获取歌词

6.总结

7.完整代码

1.分析页面

这一次我们来爬取网易云音乐,爬取歌单内的所有歌曲的图片和歌词,最终的结果是我们只要输入歌单的id,我们就可以直接下载歌单内所有歌曲的图片和歌词,并且以自己想要的命名格式统一命名。

上图是这次的演示歌单,id为973185551。每个歌曲也是有对应的id,通过右键检查第一首歌曲,可以发现这首歌的id为1370008169。

进入歌曲页面,检查图片,会发现图片的url与id是看不出有一点关系的,也就是我们只能进入到歌曲的页面才能获得图片的url。

2.获取歌曲的id

注意:想要爬取真正的页面信息,必须将原url中的 /# 删除,否则无法通过url得到正确的源代码。

原本的歌单url:https://music.163.com/#/playlist?id=973185551

更改后的url:https://music.163.com/playlist?id=973185551

# encoding: utf-8

import requests

import re

import os

import json

# 获取网页源代码

def get_page(url):

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'

}

response = requests.get(url, headers=headers)

return response.text

# 获得歌曲ID

def get_id(url_list):

text = get_page(url_list)

ids = re.findall(r, text, re.DOTALL)

return ids

def main():

url = 'https://music.163.com/playlist?id=973185551' # 歌单url

ids = get_id(url)

for id in ids:

print(id)

if __name__ == '__main__':

main()

运行的部分结果:

我们可以发现,我们已经提取出了歌单里所有歌的id。

3.歌曲信息

同样的,我们想要得到网页源代码,就必须将 /# 去掉,变为:

view-source:https://music.163.com/song?id=1370008169

我们可以直接获取meta下的信息

# 获取歌曲名

def get_name(url_song):

text = get_page(url_song)

song_name = re.findall(r'', text, re.DOTALL)

song_authors = re.findall(r'', text, re.DOTALL)

name = song_name[0] + ' - ' + song_authors[0]

return name

运行的部分结果:

4.获取歌曲图片url

歌曲图片的url也在一个meta标签下

# 获得歌曲图

def get_img(url_song):

text = get_page(url_song)

url_img = re.findall(r'', text, re.DOTALL)[0]

return url_img

运行的部分结果:

5.获取歌词

获取网易云音乐的歌词挺简单的,它们可以通过直接访问url获得。比如

http://music.163.com/api/song/lyric?id=1370008169&lv=1&kv=1&tv=-1

我们只需要改变id,就可以获得对应歌曲的歌词。

由于这一段信息是json格式,所以读取的时候可以使用json的方式直接获得歌词,并写入文件储存。

# 获取歌词

def get_lyric(id, name):

url_lyric = "http://music.163.com/api/song/lyric?id=" + id + "&lv=1&kv=1&tv=-1"

text = get_page(url_lyric)

judge_lyric = re.findall(r'{"nolyric":true,.*?}', text, re.DOTALL)

if judge_lyric:

print(str(name) + '无歌词\n')

else:

# 用json获取歌词

json_obj = json.loads(text)

initial_lyric = json_obj['lrc']['lyric']

root = "D://lyric//"

path = root + name + '.lrc'

try:

if not os.path.exists(root):

os.mkdir(root)

if not os.path.exists(path):

with open(path, 'w') as f:

f.write(initial_lyric)

f.close()

except:

return None

6.总结

当爬取网易云音乐的时候,网址出现的/#对我产生了很大的麻烦,白白浪费了三四个小时去修改我的访问方式,总在怀疑我是get用错了,又或者是headers写错了,对网页直接右键源代码也出现了问题。直到我去删除了网址中的/#,才正常的获得了源代码。使用正则去获取信息,主要是因为在获取简单的信息时,直接使用正则其实还是比较简单的,缺点是当歌曲变多后,使用正则会让程序执行速度变慢。

由于某些歌曲是无歌词的,所以我们需要添加判断是否有歌词的语句,否则会让程序在运行时报错。上图就是无歌词时,访问url的显示结果。偷懒一下,直接用正则匹配这一段,然后if判断时就会过,执行输出歌曲无歌词的提示,并让程序依旧正常运行。

7.完整代码

# encoding: utf-8

import requests

import re

import os

import json

# 获取网页源代码

def get_page(url):

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'

}

response = requests.get(url, headers=headers)

return response.text

# 获得歌曲ID

def get_id(url_list):

text = get_page(url_list)

ids = re.findall(r, text, re.DOTALL)

return ids

# 获取歌曲名

def get_name(url_song):

text = get_page(url_song)

song_name = re.findall(r'', text, re.DOTALL)

song_authors = re.findall(r'', text, re.DOTALL)

name = song_name[0] + ' - ' + song_authors[0]

return name

# 获得歌曲图

def get_img(url_song, name):

text = get_page(url_song)

url_img = re.findall(r'', text, re.DOTALL)[0]

root = "D://pics//"

path = root + name + '.jpg'

try:

if not os.path.exists(root):

os.mkdir(root)

if not os.path.exists(path):

r = requests.get(url_img)

with open(path, 'wb') as f:

f.write(r.content)

f.close()

except:

return None

# 获取歌词

def get_lyric(id, name):

url_lyric = "http://music.163.com/api/song/lyric?id=" + id + "&lv=1&kv=1&tv=-1"

text = get_page(url_lyric)

judge_lyric = re.findall(r'{"nolyric":true,.*?}', text, re.DOTALL)

if judge_lyric:

print(str(name) + '无歌词\n')

else:

# 用json获取歌词

json_obj = json.loads(text)

initial_lyric = json_obj['lrc']['lyric']

root = "D://lyric//"

path = root + name + '.lrc'

try:

if not os.path.exists(root):

os.mkdir(root)

if not os.path.exists(path):

with open(path, 'w') as f:

f.write(initial_lyric)

f.close()

except:

return None

def main():

url = 'https://music.163.com/playlist?id=391228182' # 歌单url

ids = get_id(url)

names = []

fns_num = 1

num = len(ids)

for id in ids:

url_song = 'https://music.163.com/song?id=%s' % id

name = get_name(url_song)

get_img(url_song, name)

get_lyric(id, name)

names.append(name)

print("\r完成进度: {:.2f}%".format(fns_num * 100 / num), end="")

fns_num += 1

print('\n\n完成名单:')

for i in names:

print(i)

print('\n\n查找到的数量:' + str(num))

print('\n最终完成的数量:' + str(len(names)))

if __name__ == '__main__':

main()

运行的部分结果:

注:由于其中一首歌的名字出现“/”斜杠,导致文件无法储存,文件的命名格式是不能出现“/”。可以通过添加以下语句,将“/”转换成“、”。

s = "【贰婶/流浪的蛙蛙/HITA/冥月】世伪知贤 (用原创发声) - 贰婶、流浪的蛙蛙、HITA、冥月"

s = s.replace('/','、')

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值