大家好,我是python222_小鋒老師,看到一個不錯的基于Python的網易云音樂熱門歌單可視化大屏項目(flask+pandas+echarts+request庫),分享下哈。
項目視頻演示
【免費】基于Python的網易云音樂熱門歌單可視化大屏項目(flask+pandas+echarts+爬蟲) Python畢業設計_嗶哩嗶哩_bilibili
項目介紹
數字化時代帶動著整個社會的信息化發展,隨著數字媒體的不斷發展,現在通多媒體數字產品的內容越來越豐富,傳播影響力越來越強,以音樂為例,現在的音樂文化多樣、音樂資源也異常的豐富,在這種大數據的環境下,基于網易云音樂平臺的歌單數據,設計并實現了一個高度互動與視覺吸引力的數據可視化大屏項目。該項目通過挖掘網易云歌單的海量數據,包括但不限于歌單類型分布、熱門歌曲排行、用戶偏好分析、地域音樂風格差異等關鍵指標,為用戶、音樂創作者及平臺管理者提供直觀、全面的音樂生態洞察。采用可視化技術,如動態圖表、熱力圖、詞云等,將復雜的數據轉化為生動形象的視覺故事,不僅展現了音樂流行的趨勢與變遷,還揭示了用戶行為的深層規律。該數據可視化大屏不僅提升了音樂數據的價值密度,也為音樂行業的精準營銷、內容創作及用戶服務提供了有力的數據支持。
系統展示
部分代碼
# -*- coding: utf-8 -*-
import os
import re
import csv
import json
import time
import pymysql
import requests
from bs4 import BeautifulSoup
from multiprocessing import Pool# 老版本爬蟲響應速度慢,因為api接口(https://api.imjad.cn/)將在未來失效
# 開源方案 https://github.com/mixmoe/HibiAPI 的安裝文檔不詳細,但是提供了公開接口見'公開搭建實例'
# 于是找到 https://api.obfs.dev/docs#operation/playlist_api_netease_playlist_get
# 將現有接口替換下就實現了
# coder: SuccessKey# 請求頭
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}# 歌單類型鏈接
type_url = "https://music.163.com/discover/playlist"# 連接數據庫
db = pymysql.connect(host="localhost",user="root",password="123456",port=3306,db="cloudmusic"
)cursor = db.cursor()"""獲取歌單類型"""def get_playlist_type(url):response = requests.get(url=url, headers=headers)html = response.textsoup = BeautifulSoup(html, 'lxml')types = [t.text for t in soup.select("a.s-fc1")][1:]# for t in types:# print(t)return types"""獲取歌單id"""# CSV文件名,用于保存已爬取的歌單ID和類型
csv_filename = "playlist_ids.csv"# 獲取歌單ID并保存
def get_playlist_id(url):response = requests.get(url=url, headers=headers)html = response.textsoup = BeautifulSoup(html, 'lxml')# 獲取所有的歌單 IDids = [re.sub(r"\D+", "", i['href']) for i in soup.select("a.msk")]t = re.search('https.*cat=(.*)&limit', url).group(1)# 打印出所有的歌單ID和類型(調試用)print(f"獲取到的歌單ID: {ids}, 歌單類型: {t}")# 保存歌單ID和類型到CSV文件save_ids_to_csv(ids, t)# 保存ID和類型到CSV
def save_ids_to_csv(ids, t):# 打開文件并保存ID和類型with open(csv_filename, mode='a', newline='', encoding='utf-8') as file:writer = csv.writer(file)for id in ids:writer.writerow([id, t]) # 保存ID和類型到文件中print(f"已保存 {len(ids)} 個歌單ID 和類型到 {csv_filename}")# 讀取CSV文件中的已存在ID和類型
def load_ids_from_csv():existing_ids = {} # 使用字典來存儲 ID 和類型的配對if os.path.exists(csv_filename):with open(csv_filename, mode='r', newline='', encoding='utf-8') as file:reader = csv.reader(file)for row in reader:existing_ids[row[0]] = row[1] # ID作為key,類型作為valuereturn existing_ids"""獲取歌單信息"""def get_playlist_info(ids, t):# playlist_url = "https://api.imjad.cn/cloudmusic/?type=playlist&id={}"# playlist_url = "https://api.obfs.dev/api/netease/playlist?id={}"playlist_url = "https://hibi.moecube.com/api/netease/playlist?id={}"url = playlist_url.format(ids)print(url)response = requests.get(url=url, headers=headers)json_text = response.text# print(url)# print(response.text)json_playlist = json.loads(json_text)["playlist"]# 歌單ID、歌單名、歌單類型、標簽、創建時間、最后更新時間、播放量、收藏量、轉發量、評論數# 用戶名、性別、用戶類型、VIP類型、省份、城市playlistID = str(json_playlist["id"])name = json_playlist["name"]playlistType = ttags = "、".join(json_playlist["tags"])createTime = time.strftime("%Y-%m-%d", time.localtime(int(str(json_playlist["createTime"])[:-3])))updateTime = time.strftime("%Y-%m-%d", time.localtime(int(str(json_playlist["updateTime"])[:-3])))tracks_num = len(json_playlist["trackIds"])playCount = json_playlist["playCount"]subscribedCount = json_playlist["subscribedCount"]shareCount = json_playlist["shareCount"]commentCount = json_playlist["commentCount"]nickname = json_playlist['creator']['nickname']gender = str(json_playlist['creator']['gender'])userType = str(json_playlist['creator']['userType'])vipType = str(json_playlist['creator']['vipType'])province = str(json_playlist['creator']['province'])city = str(json_playlist['creator']['city'])# 匹配性別、省份、城市代碼if gender == '1':gender = '男'else:gender = '女'# 打開行政區代碼文件with open("country.csv", encoding="utf-8") as f:rows = csv.reader(f)for row in rows:if row[0] == province:province = row[1]if row[0] == city:city = row[1]if province == '香港特別行政區':city = '香港特別行政區'if province == '澳門特別行政區':city = '澳門特別行政區'if province == '臺灣省':city = '臺灣省'if province == str(json_playlist['creator']['province']):province = '海外'city = '海外'if city == str(json_playlist['creator']['city']):city = provinceplaylist = [playlistID, name, playlistType, tags, createTime, updateTime,tracks_num, playCount, subscribedCount, shareCount, commentCount,nickname, gender, userType, vipType, province, city]print(playlist)save_to_playlists(playlist)# def get_playlist_info(ids, t):
# # playlist_url = "https://api.imjad.cn/cloudmusic/?type=playlist&id={}"
# # playlist_url = "https://api.obfs.dev/api/netease/playlist?id={}"
# playlist_url = "https://hibi.moecube.com/api/netease/playlist?id={}"
# urls = [playlist_url.format(i) for i in ids]
#
# for url in urls:
# print(url)
# try:
# response = requests.get(url=url, headers=headers)
# json_text = response.text
# # print(url)
# # print(response.text)
# json_playlist = json.loads(json_text)["playlist"]
# except:
# continue
#
# # 歌單ID、歌單名、歌單類型、標簽、創建時間、最后更新時間、播放量、收藏量、轉發量、評論數
# # 用戶名、性別、用戶類型、VIP類型、省份、城市
# playlistID = str(json_playlist["id"])
# name = json_playlist["name"]
# playlistType = t
# tags = "、".join(json_playlist["tags"])
# createTime = time.strftime("%Y-%m-%d", time.localtime(int(str(json_playlist["createTime"])[:-3])))
# updateTime = time.strftime("%Y-%m-%d", time.localtime(int(str(json_playlist["updateTime"])[:-3])))
# tracks_num = len(json_playlist["trackIds"])
# playCount = json_playlist["playCount"]
# subscribedCount = json_playlist["subscribedCount"]
# shareCount = json_playlist["shareCount"]
# commentCount = json_playlist["commentCount"]
# nickname = json_playlist['creator']['nickname']
# gender = str(json_playlist['creator']['gender'])
# userType = str(json_playlist['creator']['userType'])
# vipType = str(json_playlist['creator']['vipType'])
# province = str(json_playlist['creator']['province'])
# city = str(json_playlist['creator']['city'])
#
# # 匹配性別、省份、城市代碼
# if gender == '1':
# gender = '男'
# else:
# gender = '女'
#
# # 打開行政區代碼文件
# with open("country.csv", encoding="utf-8") as f:
# rows = csv.reader(f)
#
# for row in rows:
# if row[0] == province:
# province = row[1]
# if row[0] == city:
# city = row[1]
#
# if province == '香港特別行政區':
# city = '香港特別行政區'
# if province == '澳門特別行政區':
# city = '澳門特別行政區'
# if province == '臺灣省':
# city = '臺灣省'
# if province == str(json_playlist['creator']['province']):
# province = '海外'
# city = '海外'
# if city == str(json_playlist['creator']['city']):
# city = province
#
# playlist = [playlistID, name, playlistType, tags, createTime, updateTime,
# tracks_num, playCount, subscribedCount, shareCount, commentCount,
# nickname, gender, userType, vipType, province, city]
# print(playlist)
# save_to_playlists(playlist)"""保存到數據庫"""
# 保存歌單信息到數據庫,如果已存在就更新
def save_to_playlists(l):sql = """INSERT INTO playlists(id, name, type, tags, create_time, update_time, tracks_num, play_count, subscribed_count, share_count, comment_count, nickname, gender, user_type, vip_type, province, city)VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)ON DUPLICATE KEY UPDATE name = VALUES(name), type = VALUES(type), tags = VALUES(tags), create_time = VALUES(create_time), update_time = VALUES(update_time), tracks_num = VALUES(tracks_num), play_count = VALUES(play_count), subscribed_count = VALUES(subscribed_count), share_count = VALUES(share_count), comment_count = VALUES(comment_count), nickname = VALUES(nickname), gender = VALUES(gender), user_type = VALUES(user_type), vip_type = VALUES(vip_type), province = VALUES(province), city = VALUES(city)"""try:cursor.execute(sql, (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8], l[9], l[10],l[11], l[12], l[13], l[14], l[15], l[16]))db.commit()except Exception as e:db.rollback()print(f"Error: {e}")def main():types = get_playlist_type(type_url)urls = []for t in types:for i in range(37):url = "https://music.163.com/discover/playlist/?order=hot&cat={0}&limit=35&offset={1}".format(t, i * 35)print(url)urls.append(url)pool = Pool(10)for url in urls:pool.apply_async(get_playlist_id, args=(url,))pool.close()pool.join()def main2():# print(load_ids_from_csv())data = load_ids_from_csv()for k, v in data.items():# print(k, v)try:get_playlist_info(k, v)except:passif __name__ == "__main__":# main()main2()
源碼下載
鏈接:https://pan.baidu.com/s/1JcGAqWi2yBa12SlUHXQgeQ
提取碼:1234