python爬取⽹易云⾳乐下载
⼀、选题背景
由于现在的⾳乐版权问题,很多⾳乐分布在各个平台的⾳乐播放器,⽽版权问题也使很多⼈⾮常的困扰,从⽽不到⾳乐的资源。因此为帮助使⽤⽹易云的伙伴们,更好的到各个平台的资源,听到更多⾃⼰喜欢的歌。
⼆、爬⾍⽅案设计
1.实现功能
2.具体实现
1.搜索部分
3.下载歌曲
1.再次获取信息
2.下载
4.结语
三、实现功能
可以分别对歌名,歌⼿,歌单进⾏搜索,搜索歌曲和歌单会列出页⾯第⼀页所显⽰的所有歌曲或歌单及其id以供选择下载,搜索歌⼿会下载⽹易云⾳乐列表显⽰第⼀位歌⼿的所有热门歌曲。
四、具体实现
选择selenium + chrome 获取js渲染后的页⾯源码,并通过xpath提取想要的信息
python代码:
1 import requests
2 from urllib import request
3 from lxml import etree
4 from selenium import webdriver
5 import platform
6 import os
7 import time
8
9
10 headers = {
11 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36',
12 'Host': 'music.163',
13 'Referer': 'music.163/'
14 }
通过检查元素发现在⽹页的这⼀部分存在歌曲链接和名字
通过selenium获得页⾯源码
1 def selenium_get_html(url):
2 """通过selenium获得页⾯源码"""
3 # ⽆界⾯启动chrome
4 options = webdriver.ChromeOptions()
5 options.add_argument(
6 'User-Agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"')
7 options.add_argument('--headless')
8 driver = webdriver.Chrome(chrome_options=options)
(url)
10 # 歌曲信息在frame框架内,进⼊frame框架得到源码
11 driver.switch_to.frame('contentFrame')
12 return driver.page_source
同理,在搜索歌单和歌⼿时检查元素也会发现类似的情况
得到具体信息
1 # 提取歌曲名称,演唱者姓名,和歌曲id以供选择
2 def search_input_song(url):
3 """获取歌曲名字和id"""
4 html = selenium_get_html(url)
5
6 root = etree.HTML(html)
7 id = root.xpath('//div[@class="srchsongst"]//div[@class="td w0"]//div[@class="text"]/a[1]/@href')
8 artist = root.xpath('//div[@class="srchsongst"]//div[@class="td w1"]//div[@class="text"]/a[1]/text()')
9 name = root.xpath('//div[@class="srchsongst"]//div[@class="td w0"]//div[@class="text"]//b/@title')
10
11 id = [i.strip('/song?id==') for i in id]
12 return zip(name, artist, id)
13
14 # 歌⼿默认选择第⼀位,所以仅得到第⼀位歌⼿的id
15 def search_input_artist(url):
16 """获取歌⼿id"""
17 html = selenium_get_html(url)
18
19 root = etree.HTML(html)
20 id = root.xpath('//div[@class="u-cover u-cover-5"]/a[1]/@href')
21
22 return id[0].strip('/artist?id==')
23
24 # 提取歌单名称,和歌单id以供选择
25 def search_input_playlist(url):
26 """获取歌单名字和id"""
27 html = selenium_get_html(url)
28
29 root = etree.HTML(html)
30 id = root.xpath('//div[@class="u-cover u-cover-3"]/a/@href')
31 name = root.xpath('//div[@class="u-cover u-cover-3"]//span/@title')
32
33 id = [i.strip('/playlist?id==') for i in id]
34 return zip(name, id)
五、下载歌曲
python代码:
1 # url为歌单或歌⼿的地址
2 def get_url(url):
3 """从歌单中获取歌曲链接"""
4 req = (url, headers=headers)
5
6 root = etree.)
7 items = root.xpath('//ul[@class="f-hide"]//a')
8 print(items)
9
10 return items
1 # song_id为歌曲id, song_name为歌曲名称
2 def download_song(song_id, song_name):
3 """通过外链下载歌曲"""
4
5 url = 'music.163/song/media/outer/url?id={}.mp3'.format(song_id)
6
7 # get请求设置禁⽌⽹页跳转,即allow_redirects=False
8 req = (url, headers=headers, allow_redirects=False)
9 song_url = req.headers['Location']
10 try:
11 # path在主函数中输⼊
12 request.urlretrieve(song_url, path + "/" + song_name + ".mp3")
13 print("{}--下载完成".format(song_name))
14 except:
15 print("{}--下载失败".format(song_name))
3.完整代码
1 import requests
2
3 from urllib import request
4 from lxml import etree
5 from selenium import webdriver
6
7html播放音乐代码
8 import platform
9 import os
10 import time
11
12
13 headers = {
14 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36',
15 'Host': 'music.163',
16 'Referer': 'music.163/'
17 }
18
19
20
21 def get_url(url):
22 """从歌单中获取歌曲链接"""
23 req = (url, headers=headers)
24 root = etree.)
25 items = root.xpath('//ul[@class="f-hide"]//a')
26 print(items)
27 return items
28
29
30
31 def download_song(song_id, song_name):
32 """通过外链下载歌曲"""
33 url = 'music.163/song/media/outer/url?id={}.mp3'.format(song_id)
34
35 req = (url, headers=headers, allow_redirects=False)
36
37 song_url = req.headers['Location']
38 try:
39 request.urlretrieve(song_url, path + "/" + song_name + ".mp3")
40 print("{}--下载完成".format(song_name))
41 except:
42 print("{}--下载失败".format(song_name))
43
44
45
46 def download(items):
47 """全部歌曲下载"""
48 for item in items:
49 song_id = ('href').strip('/song?id=')
50 song_name =
51 download_song(song_id, song_name)
52 print("-------下载完成-------")
53
54
55 def artist_id_down(id):
56 """根据歌⼿id下载全部歌曲"""
57 artist_url = 'music.163/artist?id={}'.format(id)
58 items = get_url(artist_url)
59 download(items)
60
61
62 def playlist_id_down(id):
63 """根据歌单id下载全部歌曲"""
64 playlist_url = 'music.163/playlist?id={}'.format(id)
65 items = get_url(playlist_url)
66 download(items)
67
68
69 def get_song_name(url):
70 """在歌曲页⾯获得名字"""
71 req = (url, headers=headers)
72 root = etree.)
73 name = root.xpath('//em[@class="f-ff2"]/text()')
74 return name[0]
75
76
77 def song_id_down(id):
78 """根据歌曲id下载"""
79 url = 'music.163/song?id={}'.format(id)
80 name = get_song_name(url)
81 download_song(id, name)
82
83
84 def selenium_get_html(url):
85 """通过selenium获得页⾯源码"""
86 options = webdriver.ChromeOptions()
87
88
89 options.add_argument(
90 'User-Agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"')
91 options.add_argument('--headless')
92 driver = webdriver.Chrome(chrome_options=options)
93 (url)
94 driver.switch_to.frame('contentFrame')
95 driver.close()
96 return driver.page_source
97
98
99 def search_input_song(url):
100 """获取歌曲名字和id"""
101 html = selenium_get_html(url)
102 root = etree.HTML(html)
103
104 id = root.xpath('//div[@class="srchsongst"]//div[@class="td w0"]//div[@class="text"]/a[1]/@href')
105 artist = root.xpath('//div[@class="srchsongst"]//div[@class="td w1"]//div[@class="text"]/a[1]/text()')
106 name = root.xpath('//div[@class="srchsongst"]//div[@class="td w0"]//div[@class="text"]//b/@title')
107
108
109 id = [i.strip('/song?id==') for i in id]
110 return zip(name, artist, id)
111
112
113 def search_input_artist(url):
114 """获取歌⼿id"""
115 html = selenium_get_html(url)
116 root = etree.HTML(html)
117 id = root.xpath('//div[@class="u-cover u-cover-5"]/a[1]/@href')
118 return id[0].strip('/artist?id==')
119
120
121 def search_input_playlist(url):
122 """获取歌单名字和id"""
123 html = selenium_get_html(url)
124 root = etree.HTML(html)
125 id = root.xpath('//div[@class="u-cover u-cover-3"]/a/@href')
126 name = root.xpath('//div[@class="u-cover u-cover-3"]//span/@title')
127 id = [i.strip('/playlist?id==') for i in id]
128 return zip(name, id)
129
130
131 def main(name, choose_id):
132 if choose_id == 1:
133 url = 'music.163/#/search/m/?s={}&type=1'.format(name)
134 com = search_input_song(url)
135 ids = []
136 for i, j, k in com:
137 ids.append(k)
138 print("歌曲名称:{0}-------演唱者:{1}-------id:{2}".format(i, j, k))
139 while True:
140 id = input("请输⼊需要下载的id(输⼊q退出):")
141 if id == 'q':
142 return
143 if id in ids:
144 song_id_down(id)
145 return
146 print("请输⼊正确的id")
147
148
149 elif choose_id == 2:
150 url = 'music.163/#/search/m/?s={}&type=100'.format(name)
151 id = search_input_artist(url)
152 artist_id_down(id)
153 elif choose_id == 3:
154 url = 'music.163/#/search/m/?s={}&type=1000'.format(name)
155 com = search_input_playlist(url)
156 ids = []
157 for i, j in com:
158 ids.append(j)
159 print("歌单名称:{0}-------id:{1}".format(i, j))
160 while True:
161 id = input("请输⼊需要下载的id(输⼊q退出):")
162 if id == 'q':
163 return
164 if id in ids:
165 playlist_id_down(id)
166 return
167 print("请输⼊正确的id(输⼊q退出):")
168
169
170 def recognition():
171 """判断系统,执⾏清屏命令"""
172 sysstr = platform.system()
173 if (sysstr == "Windows"):
174 os.system('cls')
175 elif (sysstr == "Linux"):
176 os.system('clear')
177 if __name__ == '__main__':
178 path = input("请输⼊完整路径地址:")
179 if not ists(path):
180 os.makedirs(path)
181 while True:
182 print("=========================")
183 print("请按提⽰选择搜索类型:")
184 print("1.歌曲")
185 print("2.歌⼿")
186 print("3.歌单")
187 print("4.退出")
188 print("=========================")
189 choose_id = int(input("搜索类型:"))
190
191
192 if choose_id == 4:
193 break
194 elif choose_id != 1 and choose_id != 2 and choose_id != 3:
195 print("请按要求输⼊")
196 continue
197 else:
198 recognition()
199 name = input("请输⼊搜索内容:")
200 main(name, choose_id)
201 print("3秒后返回主页⾯")
202 time.sleep(3)
6、结语
这篇⽂章和代码是⽹易云⾳乐的下载,⾥⾯的数据⽐较全⾯,⼤块可分为:评论⽤户信息、评论信息、⽤户权限信息、评论回复信息等。本⽂爬取的数据有,评论⼈昵称、评论时间、评论内容、⽤户ID。这篇⽂章就到这⾥了,如果有不⾜的地⽅欢迎各位⼤佬指定⼀下,谢谢!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论