网易云音乐歌曲信息爬取,包括标题、歌手、封面等

本文最后更新于:2024年2月8日 下午

实现

目标:从网易云音乐爬取歌曲信息并写入下载的歌曲

分析

浏览器中直接复制出来的链接与从客户端复制出来的链接有一点小小的区别,

1
2
https://music.163.com/#/song?id=41643734(浏览器)
https://music.163.com/song?id=41643734(客户端)

有”/#”的链接爬取下来的内容因为套了一层iframe而没有歌曲信息,没有”/#”的链接是原始的歌曲页面,内容中一些<meta>标签中有歌曲信息。

1
2
3
4
<meta property="og:title" content="Fireflies" />
<meta property="og:image" content="http://p1.music.126.net/dorTkbeN6ioIYOr1SwGRtA==/109951168167193142.jpg" />
<meta property="og:music:artist" content="Owl City" />
<meta property="og:music:album" content="OO's Hits It's Party Time"/>

爬取

歌词api见以前的文章两个网易云音乐api
先下载页面,再使用bs4筛选出来需要的歌曲信息(在<meta>标签的content属性中)

本人代码水平低,仅供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from bs4 import BeautifulSoup
from requests import get,head
from fake_useragent import UserAgent

id = '41643734' # 链接中的id

ua = UserAgent()
url = f"https://music.163.com/song?id={id}"
headers = {
"User-Agent": ua.random,

}
response = get(url=url,headers=headers)
a = response.text
bs = BeautifulSoup(a,'html.parser')
contents = []

for i in bs.find_all('meta'): # 搜索所有meta标签
try:
i['property'] # 筛选带有property属性
contents.append(i['content'])
except:
pass

title = contents[1]
artist = contents[9]
album = contents[10]
img_url = contents[3]

完整代码

在爬取信息的基础上添加了下载歌曲、歌词、封面等信息并写入歌曲文件的功能

本人代码水平低,仅供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 所有名为data的变量名都是想不出来名的的临时变量

from bs4 import BeautifulSoup
from requests import get,head
from os.path import isdir
from os import mkdir
from shutil import copy
from sys import argv,exit
from eyed3 import load
from loguru import logger
from fake_useragent import UserAgent


true = True

def main(id,path=0):
try:
# 复制文件

if isdir('output'):
pass
else:
mkdir('output')

ua = UserAgent()
url = f"https://music.163.com/song?id={id}"
headers = {
"User-Agent": ua.random,

}
response = get(url=url,headers=headers)
a = response.text
bs = BeautifulSoup(a,'html.parser')
contents = []
for i in bs.find_all('meta'): # 找到meta
try:
i['property']
contents.append(i['content'])
except:
pass
title = contents[1]
artist = contents[9]
album = contents[10]
img_url = contents[3]
save_name = f'{title} - {artist}'.replace('/',' ') # 防止多个歌手名中有斜杠导致无法保存文件

# 获取文件
if path: # 传入路径
copy(path,'output\\'+path.split('\\')[-1])
save_name = ''
# 以下四行只是为了得到没有扩展名的歌曲文件名称
data = path.split('\\')[-1].split('.')
del(data[-1])
for i in data:
save_name += i
else:
logger.info('下载音乐')
song_url = head(f'https://music.163.com/song/media/outer/url?id={id}.mp3',headers=headers).headers['Location']
if song_url == 'http://music.163.com/404':
logger.error('无资源')
else:
data = get(song_url)
with open('output\\'+save_name+'.mp3','wb') as f:
f.write(data.content)

# 歌词
logger.info('下载歌词')
data = get('https://music.163.com/api/song/media?id='+id).text
try:
lrc = eval(data)['lyric']
with open('output\\'+save_name+'.lrc', 'w', encoding='utf-8') as f:
f.write(lrc)
except:
logger.info('无歌词')

logger.info('下载封面')
data = get(img_url).content


logger.info(f'''
-----歌曲信息-----
歌曲名:{title}
作曲家:{artist}
专辑:{album}''')
logger.info('写入信息')
write_tags(save_name,title,artist,album,data)
logger.success('成功:'+'output\\'+save_name+'.mp3')
except Exception as e:
logger.error(str(e))


def write_tags(save_name,title,artist,album,data):
audioFile = load(path='output\\'+save_name+'.mp3')
audioFile.tag.artist = artist
audioFile.tag.title = title
audioFile.tag.album = album
audioFile.tag.images.set(3, data, 'image/jpeg', u'Cover')
audioFile.tag.save()



try:
data = argv[1]
if len(argv) > 2:
path = argv[2]
else:
path = ''
except Exception as e:
logger.error(str(e))
print(f'用法:\n{argv[0]} [网易云音乐歌曲id或url] [需要写入信息的歌曲文件路径(可选)]')
exit()

try:
id = str(int(data))
except:
try:
id = data.split('id=')[1].split('&')[0]
except Exception as e:
logger.error(str(e))
logger.info('id:'+id)
main(id,path)

网易云音乐歌曲信息爬取,包括标题、歌手、封面等
https://g-haoyu.top/2024/02/05/网易云音乐歌曲信息爬取,包括标题、歌手、封面等/
作者
Haoyu
发布于
2024年2月5日
更新于
2024年2月8日
许可协议