python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)

目录

  • 具体思路
  • 代码部分
    • 获取歌曲名称和歌手
    • 获取歌曲播放页的url
    • 获取音乐下载地址
    • 将获取到的音乐信息添加到MySQL中
  • 完整代码

获取酷狗音乐榜单中的音乐信息,这里我以“网络红歌榜”为例

python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第1张图片
获取榜单中的 “音乐名称”,“歌手”,“音乐下载地址”,并将这些信息存储到MySQL数据库中,最后完成的效果图如下:
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第2张图片
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第3张图片

具体思路

查看榜单的源代码,我们可以得到歌曲播放页的url,歌曲名称和歌手
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第4张图片
获取歌曲名称和歌手

所以我们可以直接在源代码中将歌曲名称和歌手提取出来

获取歌曲下载地址

进入到音乐播放页,F12查看一下
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第5张图片
进入到播放页查看源代码竟然能够看到歌曲的下载地址,这样一来,事情就变得简单了,直接使用播放页的url进行爬取但就是获取不到这个地址,原本以为是哪里出了问题,结果右键查看源代码,源代码中压根就没有这个url

所以要注意的是,虽然这里能够看到音乐的下载地址,但是当你右键查看源代码时是看不到的,因为这里的下载地址是动态添加进去的不是事先写进去的,看来还是想的太过简单了

既然在这里获取下载地址不行,那我们就换一种途径,在网页的全部文件中搜索下载地址的部分关键字,我们可以得到这个文件
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第6张图片
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第7张图片
展开这个文件我们可以得到音乐的下载地址
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第8张图片
既然可以从这个文件中获取到歌曲的下载地址,那我们接下来就可以对这个文件的url进行分析
在这里插入图片描述
乍一看似乎没有什么规律,但是我们可以对其进行缩减,只保留最关键的部分,经过反复的测试,文件的url可以缩减为这三个部分的组成
在这里插入图片描述
这个文件的url可以写成:

https://wwwapi.kugou.com/yy/index.php?r=play/getdata&hash=???&album_id=???

那我们现在要获取的就是每首歌曲的hash值和album_id值

再次查看榜单的源代码,在最后我们可以看到一条重要数据
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第9张图片
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第10张图片
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第11张图片

在这条数据中就包含了榜单中每首歌曲的hash值和album_id值,所以我们可以通过这条数据将我们需要的值提取出来,然后将其组合成url,如图:
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第12张图片
python爬虫:爬取酷狗音乐榜单中的音乐信息并存储到MySQL(附源码)_第13张图片
访问我们合成的url就可以获取到歌曲的下载地址了

代码部分

获取歌曲名称和歌手

# 榜单网页url
music_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

# 榜单网页url
music_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_id
        else:
            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"}
    # 循环得到的存储音乐信息的网页url
    for 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 etree
import re
from bs4 import BeautifulSoup
# 连接数据库的模块
import pymysql

music_info_url_list = []
music_download_url_list = []

# 榜单网页url
music_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_id
        else:
            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"}
    # 循环得到的存储音乐信息的网页url
    for 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()

你可能感兴趣的:(Python,数据库,python,数据库,mysql)