用到的python库
import requests
import json
import time
import os
from urllib import parse
爬虫其实挺好学的,能够从网页里,分析并提取有用的信息才是关键。
一、分析网页:
在搜索框,输入想要搜索的歌手名。
歌手专辑页面
二、 选一首歌曲并播放,F12调出控制台,选Notwork
在这张页面里, 我们很容易的发现,有这首歌的mp3链接,复制出来,的确是这首歌,点击headers,发现(url = https://win-web-ra01-sycdn.kuwo.cn/1b1cdd2d3dfb49a62a047eae1e09da95/5f8f78a8/resource/n1/128/59/30/3018701453.mp3),最后的数字可能就是这首歌的id,复制。
点击右侧Name栏,按ctrl F,弹出搜索框,把3018701453复制进去回车,找到了,是不是很容易啊,这样我们就有了这首歌对应的headers。
Request URL:http://www.kuwo.cn/url?format=mp3&rid=157606&response=url&type=convert_url3&br=128kmp3&from=web&t=1603238057496&httpsStatus=1&reqId=90947090-132f-11eb-b50a-e3b44610be66
这就是歌曲的真实地址,可以通过解析这个网址,提取json数据,得到mp3的地址。
三、多分析几首歌,找Request UR的规律:
分析发现rid的值每一首歌都在变,现在分析rid的值是什么意思
回到歌手专辑页面,F12检查发现
rid的值是歌曲链接的一部分,也是歌曲播放页面地址,那么现在开始找rid
在Notwork里 按ctrl F 在右侧的框了把rid的值粘贴上 这里以rid=157606为例
查找到了3个数据,分别点击这三个(查找到的数据多的时候,先把鼠标放上去,会有内容提示,对于找列表形式的数据及其有效),发现第二个里有我们要找大内容,在Response里复制数据
用在线的json解析器解析。
这样,我们需要的所有信息就都找到了,在分析headers时发现,Request URL:
http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key=张学友&pn=1&rn=30&httpsStatus=1&reqId=64aafb11-133a-11eb-8499-01532e3636de
key=张学友,是歌手的名字。
通过点击下一页发现:
pn是页数,rn是一页30条数据,所有直接把Request URL改成https://www.kuwo.cn/api/www/search/searchMusicBykeyWord?其余的部分拼接进去。
歌手专辑页面的Referer和其他页面不一样,写代码的过程中发现没有Referer无法下载,于是就加上了。
四、关于网页地址的拆分:
现在就可以写代码了,完整的代码如下:
import requests
import json
import time
import os
from urllib import parse
import re
#都是def 去重新学进程池 后期进行完善
def main():
url = 'https://www.kuwo.cn/api/www/search/searchMusicBykeyWord?'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/85.0.4183.102 Safari/537.36',
'Cookie': '_ga=GA1.2.1085410153.1598345637; _gid=GA1.2.1026019446.1600844003; _gat=1; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1600870624,1600875780,1600915625,1600915701; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1600915701; kw_token=6GE3CJVWBPB',
'csrf': '6GE3CJVWBPB',
'Referer': 'http://www.kuwo.cn/search/list?key=周杰伦',
}
singer = input('歌手名:')
num = int(input('爬取页数:'))
fieldname = '酷我音乐'
#文件夹下的文件夹的创建方法,需要先拼接再进行判断
if not os.path.exists(fieldname):
os.mkdir(fieldname)
datailpath = os.path.join(fieldname, singer)
if not os.path.exists(datailpath):
os.mkdir(datailpath)
music_list = get_url(url, singer, num)
list_data = get_rid(music_list, headers)
song_list = get_song(list_data, headers)
time.sleep(0.5)
song_names = get_song_name(list_data)
save_field(song_list, song_names,datailpath, singer, headers)
def get_url(url, singer, num):
music_list = []
#拼接真实歌曲列表地址
for i in range(1, num 1):
params = {
'key': singer,
'pn': i,
'rn': '30',
'httpsStatus': '1',
}
#把params 用urlencode转换成&链接的网页链接
url_data = parse.urlencode(params)
html = url url_data
music_list.append(html)
return music_list
def get_rid(music_list, headers):
# 获取 歌曲的rid,歌曲名-
#rid 很重要 分析后得到 其值决定了歌曲真实地址
list_data = []
for html in music_list:
response = requests.get(url=html, headers=headers)
rid_list = json.loads(response.text)
rid = rid_list["data"]["list"]
for i in rid:
rid_num = i["rid"]
song_name = i["name"]
list_data.append((rid_num, song_name))
return list_data
#对歌曲名字进行了一个*(挺费的)
def get_song_name(list_data):
song_names = []
for i in list_data:
song_names.append(i[1])
return song_names
#获取真实的歌曲地址
def get_song(list_data, headers):
song_list = []
url = 'https://www.kuwo.cn/url?format=mp3&rid={}&response=url&type=convert_url3&br=128kmp3&from=web&t=1600915713043&httpsStatus=1&reqId=6f6ae631-fe10-11ea-b64a-25a6d864bc76'
for i in list_data:
try:
rid = i[0]
song_url = url.format(rid)
ret = requests.get(song_url, headers=headers)
song = json.loads(ret.text)
song_line = song["url"]
if song_line not in song_list:
song_list.append(song_line)
except OSError:
pass
continue
return song_list
#保存文件 用到了 多个列表间的一一对应方法 try的作用是 当碰到付费歌曲时,自动跳过
def save_field(song_list, song_names, datailpath, singer, headers):
t = 0
tt = {}
for i in song_names:
tt[i] = song_list[t]
t = 1
for k,v in tt.items():
try:
field_path = datailpath '/' k '.mp3'
songer = requests.get(v, headers=headers)
with open(field_path, 'wb') as f:
f.write(songer.content)
print('%s,下载成功' % k)
except OSError:
pass
continue
if __name__ == '__main__':
main()
,
Copyright © 2008-2022 秒下下载站
m.down10s.com .All Rights Reserved