目录
获取酷狗音乐榜单中的音乐信息,这里我以“网络红歌榜”为例
获取榜单中的 “音乐名称”,“歌手”,“音乐下载地址”,并将这些信息存储到MySQL数据库中,最后完成的效果图如下:
查看榜单的源代码,我们可以得到歌曲播放页的url,歌曲名称和歌手
获取歌曲名称和歌手
所以我们可以直接在源代码中将歌曲名称和歌手提取出来
获取歌曲下载地址
进入到音乐播放页,F12查看一下
进入到播放页查看源代码竟然能够看到歌曲的下载地址,这样一来,事情就变得简单了,直接使用播放页的url进行爬取但就是获取不到这个地址,原本以为是哪里出了问题,结果右键查看源代码,源代码中压根就没有这个url
所以要注意的是,虽然这里能够看到音乐的下载地址,但是当你右键查看源代码时是看不到的,因为这里的下载地址是动态添加进去的不是事先写进去的,看来还是想的太过简单了
既然在这里获取下载地址不行,那我们就换一种途径,在网页的全部文件中搜索下载地址的部分关键字,我们可以得到这个文件
展开这个文件我们可以得到音乐的下载地址
既然可以从这个文件中获取到歌曲的下载地址,那我们接下来就可以对这个文件的url进行分析
乍一看似乎没有什么规律,但是我们可以对其进行缩减,只保留最关键的部分,经过反复的测试,文件的url可以缩减为这三个部分的组成
这个文件的url可以写成:
https://wwwapi.kugou.com/yy/index.php?r=play/getdata&hash=???&album_id=???
那我们现在要获取的就是每首歌曲的hash值和album_id值
再次查看榜单的源代码,在最后我们可以看到一条重要数据
在这条数据中就包含了榜单中每首歌曲的hash值和album_id值,所以我们可以通过这条数据将我们需要的值提取出来,然后将其组合成url,如图:
访问我们合成的url就可以获取到歌曲的下载地址了
获取歌曲名称和歌手
# 榜单网页urlmusic_list_url = "https://www.kugou.com/yy/rank/home/1-23784.html?from=rank"# 榜单网页源代码music_list_html = requests.get(music_list_url).text# 获取歌手和歌曲名def get_music_name():element = etree.HTML(music_list_html)# @title是提取li标签中title属性的内容 获取歌曲名称和歌手music_list_name_info = element.xpath('//div[@class="pc_temp_songlist "]/ul/li/@title')return music_list_name_info
获取歌曲播放页的url
# 榜单网页urlmusic_list_url = "https://www.kugou.com/yy/rank/home/1-23784.html?from=rank"# 榜单网页源代码music_list_html = requests.get(music_list_url).text# 获取存储音乐信息的网页url 存储到列表中 返回值为列表def get_music_info_url():soup = BeautifulSoup(music_list_html,features="lxml")script = soup.find_all('script')[-1]# print(script)# print(type(script))# 查找符合正则表达式的字符串 此时script变量为bs4格式 我们需要将其转化为字符串格式info = re.findall(r'\[.*\]',str(script))[1]# print(info)# 替换符合正则表达式的字符串info = re.sub(r'\[|\]',"",info)# print(type(info))# 分割符合正则表达式的字符串info = re.split(r'\},\{',info)# print(info)for i in range(len(info)):# 获取hash属性值hash = re.findall(r'H.*?,',info[i])[0].split('"')[2]# 获取album_id属性值album_id = re.findall(r'album_id.*?,',info[i])[0].split(":")[1].replace(",","")# print(album_id)if len(hash) > 0 and len(album_id) > 0:music_info_url = "https://wwwapi.kugou.com/yy/index.php?r=play/getdata&hash=" + hash + "&album_id=" + album_idelse:print(str(i) + " " + "为空")# 将音乐信息网页地址存储到列表中music_info_url_list.append(music_info_url)return music_info_url_list
获取音乐下载地址
# 获取音乐下载地址def get_music_download_url():# 使用请求头 不然获取不到音乐信息headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36", "cookie": "kg_mid=5177dda4cc5327932ceb0652b3abbdf4; kg_dfid=2AveiS1FiBds3dWdin1RsaQ6; kg_dfid_collect=d41d8cd98f00b204e9800998ecf8427e; Hm_lvt_aedee6983d4cfc62f509129360d6bb3d=1611227172; Hm_lpvt_aedee6983d4cfc62f509129360d6bb3d=1611237914"}# 循环得到的存储音乐信息的网页urlfor music_info_url in music_info_url_list:music_info_html = requests.get(music_info_url,headers=headers).text# print(music_info_url)# print(music_info_html)# 获取音乐下载地址music_download_url = re.findall(r'play_url.*?\.mp3',music_info_html)[0].split('"')[-1].replace("\\","")# print(music_download_url)# 将播放地址添加到列表中music_download_url_list.append(music_download_url)return music_download_url_list
将获取到的音乐信息添加到MySQL中
# 将获取到的数据添加到数据库中def put_info_to_mysql():# 连接数据库db = pymysql.connect("localhost","root","root","musicsystem")# 创建指针cursor = db.cursor()for i in range(len(music_download_url_list)):# print(music_name_list)# 歌曲名称name = music_name_list[i].split(" - ")[1]# 歌手singer = music_name_list[i].split(" - ")[0]# 播放地址url = music_download_url_list[i]print(name + " " + singer + " " + url)# SQL语句sql = """insert into musicsystem_info(Name,Singer,Time,Url) values ('{}','{}','{}','{}')""".format(name,singer,"2020.1.22",url)try:# 执行SQL语句cursor.execute(sql)# 提交db.commit()print("执行成功")except:# 添加失败时回滚db.rollback()print("执行失败")# 关闭数据库连接db.close()
命令解释:
连接数据库 db = pymysql.connect("数据库地址(本地就是localhost)", "用户名", "密码", "数据库名称")获取游标对象 cursor = db.cursor()所要执行的SQL语句 sql = """INSERT INTO 表名(列名,列名) VALUES ("插入的数据","插入的数据")"""执行SQL语句 cursor.execute(sql语句)提交到数据库执行 db.commit()关闭数据库连接 db.close()完整代码
import requests# 导入xpath模块from lxml import etreeimport refrom bs4 import BeautifulSoup# 连接数据库的模块import pymysql music_info_url_list = []music_download_url_list = []# 榜单网页urlmusic_list_url = "https://www.kugou.com/yy/rank/home/1-23784.html?from=rank"# 榜单网页源代码music_list_html = requests.get(music_list_url).text# 获取歌手和歌曲名def get_music_name():element = etree.HTML(music_list_html)# @title是提取li标签中title属性的内容 获取歌曲名称和歌手music_list_name_info = element.xpath('//div[@class="pc_temp_songlist "]/ul/li/@title')return music_list_name_info# 将音乐名称和歌手 存储到列表中music_name_list = get_music_name()# 获取存储音乐信息的网页url 存储到列表中 返回值为列表def get_music_info_url():soup = BeautifulSoup(music_list_html,features="lxml")script = soup.find_all('script')[-1]# print(script)# print(type(script))# 查找符合正则表达式的字符串 此时script变量为bs4格式 我们需要将其转化为字符串格式info = re.findall(r'\[.*\]',str(script))[1]# print(info)# 替换符合正则表达式的字符串info = re.sub(r'\[|\]',"",info)# print(type(info))# 分割符合正则表达式的字符串info = re.split(r'\},\{',info)# print(info)for i in range(len(info)):# 获取hash属性值hash = re.findall(r'H.*?,',info[i])[0].split('"')[2]# 获取album_id属性值album_id = re.findall(r'album_id.*?,',info[i])[0].split(":")[1].replace(",","")# print(album_id)if len(hash) > 0 and len(album_id) > 0:music_info_url = "https://wwwapi.kugou.com/yy/index.php?r=play/getdata&hash=" + hash + "&album_id=" + album_idelse:print(str(i) + " " + "为空")# 将音乐信息网页地址存储到列表中music_info_url_list.append(music_info_url)return music_info_url_list# 获取音乐下载地址def get_music_download_url():# 使用请求头 不然获取不到音乐信息headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36", "cookie": "kg_mid=5177dda4cc5327932ceb0652b3abbdf4; kg_dfid=2AveiS1FiBds3dWdin1RsaQ6; kg_dfid_collect=d41d8cd98f00b204e9800998ecf8427e; Hm_lvt_aedee6983d4cfc62f509129360d6bb3d=1611227172; Hm_lpvt_aedee6983d4cfc62f509129360d6bb3d=1611237914"}# 循环得到的存储音乐信息的网页urlfor music_info_url in music_info_url_list:music_info_html = requests.get(music_info_url,headers=headers).text# print(music_info_url)# print(music_info_html)# 获取音乐下载地址music_download_url = re.findall(r'play_url.*?\.mp3',music_info_html)[0].split('"')[-1].replace("\\","")# print(music_download_url)# 将播放地址添加到列表中music_download_url_list.append(music_download_url)return music_download_url_list# 将获取到的数据添加到数据库中def put_info_to_mysql():# 连接数据库db = pymysql.connect("localhost","root","root","musicsystem")# 创建指针cursor = db.cursor()for i in range(len(music_download_url_list)):# print(music_name_list)# 歌曲名称name = music_name_list[i].split(" - ")[1]# 歌手singer = music_name_list[i].split(" - ")[0]# 播放地址url = music_download_url_list[i]print(name + " " + singer + " " + url)# 执行的SQL语句sql = """insert into musicsystem_info(Name,Singer,Time,Url) values ('{}','{}','{}','{}')""".format(name,singer,"2020.1.22",url)try:# 执行SQL语句cursor.execute(sql)# 提交db.commit()print("执行成功")except:# 添加失败时回滚db.rollback()print("执行失败")# 关闭数据库连接db.close()# 主函数def main():get_music_info_url()get_music_download_url()put_info_to_mysql()if __name__ == '__main__':main()