网易云音乐爬取歌单 | 臭大佬

臭大佬 2020-03-29 14:52:19 1759
Python 
简介 网易云音乐爬取歌单

分析

打开网易云音乐的网页端。我们点击更多来获取我们要的歌单。


点击分页,可以发现,这里是根据offset和limit的值来分页的,limit的默认值是35,每增加一页,offset的值增加35.最后一页是38,由此可以得到我们的基础url为https://music.163.com/#/discover/playlist/?order=hot&cat=全部&limit=35&offset=

分析每一个歌单,可以发现我们要的内容在这里面:

我们查看源代码可以发现,这些数据是动态加载的,如果直接使用requests是无法获取到节点的。我们需要用到Selenium,相关的基础介绍请先查看臭大佬教你使用 Selenium 模拟浏览器操作

爬取歌单

数据表

CREATE TABLE `song_list` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '歌单名',
  `link` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '链接',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

代码

# coding:utf-8
from bs4 import BeautifulSoup
import pymysql
from selenium import webdriver

# 引入 selenium  和实例化一个浏览器引擎
DRIVER = webdriver.Chrome()
# 链接数据库
CON = pymysql.connect(host='localhost', port=3306, user='root', password='root', db='python_test',
                      charset='utf8mb4')
# 得到一个可以执行SQL语句的光标对象
cur = CON.cursor()
BASEURL = 'https://music.163.com'

# 数据库操作
def db_write(sql):
    print(sql)
    try:
        cur.execute(sql)
        CON.commit()
        print("数据写入成功")
    except Exception as e:
        print(e)

# 获取歌单
def get_song_list(limit=35, offset=0):
    reqUrl = BASEURL + '/#/discover/playlist/?order=hot&cat=全部&limit=' + str(limit) + '&offset=' + str(offset)
    # 打开一个网页
    DRIVER.get(reqUrl)
    # 使用selenium切换frame
    DRIVER.switch_to.frame("g_iframe")
    req = DRIVER.page_source.encode('utf-8')
    soup = BeautifulSoup(req, 'lxml')
    songs = soup.select("p.dec > a")
    for song in songs:
        title = song.get('title')
        link = BASEURL + song.get('href')
        sql = "insert into song_list(title,link)values('{title}','{link}')".format(title=title, link=link)
        db_write(sql)

def get_song():
    pass


if __name__ == '__main__':
    limit = 35
    for p in range(0, 38):
        offset = limit * p
        get_song_list(limit, offset)

运行结果