Hướng dẫn toàn diện công cụ tự động nghe nhạc NetEase Music với Python
Giới thiệu tổng quan
Trong bài viết này, chúng ta sẽ tìm hiểu cách xây dựng một công cụ tự động hóa quy trình nghe nhạc trên NetEase Music (Netease Cloud Music) sử dụng Python. Công cụ này cho phép người dùng hoàn thành 300 bài hát mỗi ngày một cách tự động mà không cần thao tác thủ công.
Vấn đề thực tế
Để đạt được level cao trên NetEase Music, người dùng cần nghe ít nhất 300 bài hát mỗi ngày. Quy trình này đòi hỏi 30-60 phút thời gian liên tục, gây khó khăn cho những người bận rộn. Công cụ automation được đề cập trong bài viết giúp giải quyết vấn đề này bằng cách tự động hóa toàn bộ quy trình.
Kiến trúc hệ thống
Các thành phần chính
Hệ thống bao gồm hai thành phần chính:
- Client Application: Script Python thực hiện việc tự động nghe nhạc
- API Service: NeteaseCloudMusicApi đóng vai trò trung gian giao tiếp với server NetEase
Sơ đồ luồng hoạt động
┌─────────────┐ ┌────────────────────────┐ ┌─────────────────┐
│ Client │────▶│ NeteaseCloudMusicApi │────▶│ NetEase Server │
│ (Python) │ │ (Localhost) │ │ │
└─────────────┘ └────────────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────────┐
│ Log File │ │ Playback Data │
└─────────────┘ └─────────────────┘
Cài đặt môi trường
Yêu cầu hệ thống
- Python 3.8 trở lên
- Git
- Internet connection ổn định
Các bước cài đặt
Bước 1: Clone dự án
git clone https://github.com/nicechuan/netease-cloud-music-api.git
cd netease-cloud-music-api
npm install
Bước 2: Khởi động API service
# Mặc định service chạy trên port 3000
npm start
Bước 3: Cài đặt dependencies cho client
# Tạo virtual environment (tùy chọn nhưng khuyến nghị)
python -m venv venv
source venv/bin/activate # Linux/Mac
# hoặc
venv\Scripts\activate # Windows
# Cài đặt các thư viện cần thiết
pip install requests cryptography schedule
Cấu hình ứng dụng
Cấu trúc thư mục
project/
├── app.py # File chính của ứng dụng
├── config.json # File cấu hình
├── accounts.json # Danh sách tài khoản (nếu có nhiều)
├── requirements.txt # Dependencies
└── logs/
└── run.log # File log hoạt động
File cấu hình config.json
{
"api_endpoint": "http://localhost:3000",
"account": {
"username": "your_phone_number",
"password": "your_password",
"country_code": "86"
},
"playlist": {
"id": "your_playlist_id",
"min_songs": 300
},
"settings": {
"daily_target": 300,
"request_delay_min": 2,
"request_delay_max": 5,
"enable_md5": false,
"multi_account_mode": false
},
"notifications": {
"enabled": false,
"type": "serverchan",
"webhook_url": ""
}
}
Cách lấy Playlist ID
- Mở ứng dụng NetEase Music hoặc trang web
- Tìm playlist mong muốn
- Chọn "Chia sẻ" (Share) → "Sao chép liên kết" (Copy link)
- Trong URL, tìm tham số
id=- đó chính là Playlist ID
# Ví dụ URL: https://music.163.com/playlist?id=5234162158
# Playlist ID: 5234162158
Triển khai code chính
Module xử lý đăng nhập
import requests
import json
import time
import random
import hashlib
from datetime import datetime
class NeteaseMusicClient:
def __init__(self, config_path='config.json'):
self.config = self.load_config(config_path)
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://music.163.com/',
'Origin': 'https://music.163.com'
})
self.cookies = {}
self.played_count = 0
def load_config(self, path):
with open(path, 'r', encoding='utf-8') as f:
return json.load(f)
def encrypt_password(self, password):
"""Mã hóa mật khẩu theo format của NetEase"""
char_list = '010001'
modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
# Thực hiện mã hóa password (rút gọn)
temp = password + "password_to_encrypt"
return hashlib.md5(temp.encode()).hexdigest()
def login(self):
"""Đăng nhập vào tài khoản NetEase"""
account = self.config['account']
api_url = f"{self.config['api_endpoint']}/login/cellphone"
data = {
'phone': account['username'],
'password': account['password'],
'countrycode': account.get('country_code', '86')
}
response = self.session.post(api_url, data=data)
result = response.json()
if result.get('code') == 200:
self.cookies = response.cookies
print(f"Đăng nhập thành công: {result.get('profile', {}).get('nickname')}")
return True
else:
print(f"Đăng nhập thất bại: {result.get('message')}")
return False
Module xử lý phát nhạc
def get_playlist_tracks(self, playlist_id):
"""Lấy danh sách bài hát từ playlist"""
api_url = f"{self.config['api_endpoint']}/playlist/track/all"
params = {
'id': playlist_id,
'limit': 500, # Lấy tối đa 500 bài
'offset': 0
}
response = self.session.get(api_url, params=params)
result = response.json()
if result.get('code') == 200:
tracks = result.get('songs', [])
print(f"Đã lấy {len(tracks)} bài hát từ playlist")
return tracks
return []
def play_track(self, track_id):
"""Phát một bài hát"""
api_url = f"{self.config['api_endpoint']}/song/url"
params = {'id': track_id, 'br': 128000}
response = self.session.get(api_url, params=params)
result = response.json()
if result.get('code') == 200 and result.get('data'):
# Gọi API để record thời gian nghe
self.record_playtime(track_id)
return True
return False
def record_playtime(self, track_id):
"""Ghi nhận thời gian nghe nhạc"""
api_url = f"{self.config['api_endpoint']}/scrobble"
data = {
'id': track_id,
'sourceid': track_id,
'time': int(time.time() * 1000),
'type': 'song'
}
response = self.session.post(api_url, data=data)
return response.json().get('code') == 200
Module điều phối chính
def start_automation(self):
"""Bắt đầu quy trình tự động nghe nhạc"""
if not self.login():
return False
playlist_id = self.config['playlist']['id']
tracks = self.get_playlist_tracks(playlist_id)
if len(tracks) < self.config['playlist'].get('min_songs', 300):
print(f"Cảnh báo: Playlist có ít hơn 300 bài hát!")
daily_target = self.config['settings']['daily_target']
self.played_count = 0
print(f"Bắt đầu phát {daily_target} bài hát...")
for track in tracks:
if self.played_count >= daily_target:
break
track_id = track['id']
if self.play_track(track_id):
self.played_count += 1
print(f"Đã phát: {self.played_count}/{daily_target} - {track['name']}")
# Random delay để tránh bị phát hiện là bot
delay = random.randint(
self.config['settings']['request_delay_min'],
self.config['settings']['request_delay_max']
)
time.sleep(delay)
print(f"Hoàn thành! Đã phát {self.played_count} bài hát trong ngày hôm nay")
return True
def write_log(self, message):
"""Ghi log hoạt động"""
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_entry = f"[{timestamp}] {message}\n"
with open('logs/run.log', 'a', encoding='utf-8') as f:
f.write(log_entry)
Điểm khởi động chương trình
import schedule
import time
def main():
client = NeteaseMusicClient('config.json')
client.start_automation()
# Đặt lịch chạy hàng ngày vào lúc 1:00 sáng
schedule.every().day.at("01:00").do(main)
if __name__ == "__main__":
print("Khởi động NetEase Music Automation Tool...")
main()
# Chạy vòng lặp scheduler
while True:
schedule.run_pending()
time.sleep(60)
Các tính năng nâng cao
Hỗ trợ nhiều tài khoản
Để sử dụng tính năng quản lý nhiều tài khoản, cấu hình file accounts.json:
[
{
"username": "phone_number_1",
"password": "password_1"
},
{
"username": "phone_number_2",
"password": "password_2"
}
]
Sau đó bật chế độ multi-account trong config.json:
"settings": {
"multi_account_mode": true,
"account_switch_interval": 3600
}
Tích hợp thông báo
Công cụ hỗ trợ nhiều hình thức thông báo:
| Loại thông báo | Mô tả |
|---|---|
| ServerChan | Gửi thông báo qua WeChat |
| WxPusher | Gửi qua微信公众号 |
| Bark | Gửi thông báo đến iOS devices |
Xử lý sự cố
Các lỗi thường gặp
| Mã lỗi | Nguyên nhân | Giải pháp |
|---|---|---|
| 301 | Tài khoản hoặc mật khẩu sai | Kiểm tra lại thông tin đăng nhập |
| 400 | Playlist ID không hợp lệ | Xác nhận lại playlist ID |
| 461 | Bài hát không thể phát (license) | Chuyển sang playlist khác |
Tối ưu hóa hiệu suất
- Network: Sử dụng kết nối internet ổn định, tránh VPN gây lag
- Timing: Chạy vào ban đêm (00:00-06:00) để tránh peak hours
- Delay: Đặt delay tối thiểu 2-5 giây giữa các bài hát
Lưu ý về bảo mật
- Thông tin tài khoản được lưu trữ cục bộ trên máy người dùng
- Nên bật xác thực hai yếu tố (2FA) cho tài khoản NetEase
- Không nên chạy quá nhiều tài khoản trên cùng một IP
- Công cụ này chỉ nên được sử dụng cho mục đích học tập và cá nhân
Kết luận
Bằng cách sử dụng công cụ tự động hóa này, người dùng có thể tiết kiệm đáng kể thời gian trong việc tích lũy số giờ nghe nhạc trên NetEase Music. Tuy nhiên, cần sử dụng một cách có trách nhiệm và tuân thủ các điều khoản sử dụng của nền tảng.