Files
nypc_python_advanced/Spider/neteaseMusicSpider/main.py
iamzhaohaibo fc2838e302 update Spider/neteaseMusicSpider/main.py.
修复获取榜单奇数歌曲问题

Signed-off-by: iamzhaohaibo <941604465@qq.com>
2025-12-13 10:36:31 +00:00

120 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 导入time模块用于添加延时
import time
# 导入requests模块并重命名为req用于发送HTTP请求
import requests as req
# 导入BeautifulSoup模块用于解析HTML文档
from bs4 import BeautifulSoup
# 导入selenium的webdriver模块用于控制浏览器
from selenium import webdriver
# 导入selenium的By模块用于定位元素
from selenium.webdriver.common.by import By
# 导入selenium的Service模块用于管理浏览器驱动服务
from selenium.webdriver.chrome.service import Service
# 导入webdriver_manager的ChromeDriverManager模块用于自动管理Chrome驱动
from webdriver_manager.chrome import ChromeDriverManager
# 定义网易音乐爬虫类
class neteaseMusicSpider:
# 初始化方法,设置爬虫的基本配置
def __init__(self):
# 设置目标URL网易云音乐排行榜页面
self.url = 'https://music.163.com/discover/toplist?id=3779629'
# 设置请求头,模拟浏览器访问
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}
# 初始化排行榜列表
self.toplist = []
# 获取页面内容的方法
def get_page(self):
# 用Selenium渲染页面获取iframe
# 创建Service对象指定ChromeDriver路径
service = Service(executable_path='/Users/zhaohaibo/Desktop/chromedriver-mac-x64/chromedriver')
# 启动Chrome浏览器
driver = webdriver.Chrome(service=service)
# 访问目标网址
driver.get(self.url)
# 等待3秒让JavaScript加载完成iframe和#document
# time.sleep(3)
# 定位iframe元素
iframe_elem = driver.find_element(By.TAG_NAME, "iframe")
# 打印iframe元素信息
print(iframe_elem)
# 切换到iframe的#document上下文
driver.switch_to.frame(iframe_elem)
# 提取iframe的完整HTML内容即#document内容
iframe_html = driver.page_source
# 关闭浏览器
driver.quit()
# 返回获取到的HTML内容
return iframe_html
# 解析页面内容的方法
def parse_page(self):
try:
# 使用BeautifulSoup解析获取到的页面内容
soup = BeautifulSoup(self.get_page(), 'html.parser')
# 查找table > tbody标签下的所有的tr标签
trs = soup.select('table > tbody')[0]
# 返回找到的tr标签列表
return trs
except Exception as e:
# 捕获异常并打印错误信息
print('soup转换异常', e)
# 返回None表示解析失败
return None
# 获取歌曲信息的方法
def get_songs(self):
# 初始化歌曲字典
songs = {}
try:
# 调用parse_page方法获取解析后的HTML元素
songs_html = self.parse_page()
# 打印获取到的HTML元素及其类型
print(songs_html, '\n', type(songs_html))
# 遍历每个歌曲元素
for song in songs_html:
# 提取歌曲排行通过CSS选择器定位元素并获取排行对应文本内容
s_rank = song.select('td:nth-child(1) >div>span')[0].string
# 提取歌曲标题通过CSS选择器定位元素并获取title属性
s_title = song.select('span > a > b')[0].get_attribute_list('title')[0]
# 提取歌手信息通过CSS选择器定位元素并获取title属性
s_singer = song.select('td:nth-child(4) > div')[0].get_attribute_list('title')[0]
# 提取歌曲时长通过CSS选择器定位元素并获取文本内容
s_duration = song.select('td.s-fc3 > span')[0].string
# 提取歌曲ID通过CSS选择器定位元素
s_id = song.select('td:nth-child(2) > div > div > span')[0].get_attribute_list('data-res-id')[0]
# 打印提取到的歌曲信息
print(s_rank, s_id, s_title, s_singer, s_duration, '\n')
# 将歌曲信息添加到字典中、方便后续写入数据库、表格存储
songs[s_id] = {
'rank': s_rank,
'title': s_title,
'singer': s_singer,
'duration': s_duration
}
except Exception as e:
# 捕获异常并打印错误信息
print('异常', e)
# 程序入口点
if __name__ == '__main__':
# 创建neteaseMusicSpider类的实例
nms = neteaseMusicSpider()
# 调用get_songs方法开始爬取歌曲信息
nms.get_songs()