Python爬虫实践-网易云音乐

简介: 1、前言最近,网易的音乐很多听不到了,刚好也看到很多教程,跟进学习了一下,也集大全了吧,本来想优化一下的,但是发现问题还是有点复杂,最后另辟捷径,提供了简单的方法啊!本文主要参考 python编写GUI版网易云音乐爬虫 后改写,有兴趣的可以看看文章...

1、前言

最近,网易的音乐很多听不到了,刚好也看到很多教程,跟进学习了一下,也集大全了吧,本来想优化一下的,但是发现问题还是有点复杂,最后另辟捷径,提供了简单的方法啊!

本文主要参考 python编写GUI版网易云音乐爬虫 后改写,有兴趣的可以看看文章的GUI,了解更多知识~

2、Python + 爬虫

首先,说一下准备工作:

  • Python:需要基本的python语法基础
  • requests:专业用于请求处理,requests库学习文档中文版
  • lxml:其实可以用pythonth自带的正则表达式库re,但是为了更加简单入门,用 lxml 中的 etree 进行网页数据定位爬取。
  • re:python正则表达式处理
  • json:python的json处理库

如果大家对上面的库还比不懂,可以看看我的之前文章 《Python爬虫实践入门篇》

然后,说一下我们现在已经知道下载链接是这样的:

http://music.163.com/song/media/outer/url?id='

id 就是歌曲的id!

所以,现在我们爬虫主要的工作就是找到这个id,当然为了更好的保存,也要找到这个歌名啦!

那现在就是要找到我们需要爬虫的网站链接啦!我分析了一下,大概是下面三种:

#歌曲清单
music_list = 'https://music.163.com/#/playlist?id=2412826586' 
#歌手排行榜
artist_list = 'https://music.163.com/#/artist?id=8325'
#搜索列表 
search_list = 'https://music.163.com/#/search/m/?order=hot&cat=全部&limit=435&offset=435&s=梁静茹' 

如果你已经只是想下载一首歌,比如静茹-勇气:https://music.163.com/#/song?id=254485,那你直接就用浏览器打开 http://music.163.com/song/media/outer/url?id=254485 就可以了,没必要爬虫啊!

好啦!感觉重点都说完了,提取和解析就是用 lxml,不懂的就看我之前的文章啊 《Python爬虫实践入门篇》

3、下载歌词

如果还要下载歌词,那也很简单,通过接口,有歌曲的id就可以:

url = 'http://music.163.com/api/song/lyric?id={}&lv=-1&kv=-1&tv=-1'.format(song_id)

返回的json数据大概长这样:

{
    sgc: true,
    sfy: false,
    qfy: false,
    lrc:
    {
        version: 7,
        lyric: "[00:39.070]开了窗 等待天亮\n[00:46.160]看这城市 悄悄的 熄了光\n[00:51.850]听风的方向\n[00:55.090]这一刻 是否和我一样\n[00:58.730]孤单的飞翔\n[01:02.300]模糊了眼眶\n[01:07.760]广播里 那首歌曲\n[01:14.830]重复当时 那条街那个你\n[01:20.410]相同的桌椅\n[01:23.740]不用言语 就会有默契\n[01:27.470]这份亲密\n[01:30.560]那么熟悉\n[01:33.850]在爱里 等着你\n[01:37.480]被你疼惜 有种暖意\n[01:41.090]在梦里 全是你\n[01:43.920]不要再迟疑 把我抱紧"
    },
    klyric:
    {
        version: 0,
        lyric: null
    },
    tlyric:
    {
        version: 0,
        lyric: null
    },
    code: 200
}

剩下的也没有什么好说的啦!

4、坑点与进阶

表面上很简单,但是需要注意的是,网易返回的链接,数据是js动态加载,也就是爬虫得到的网页数据和浏览器得到的dom内容和结构不一样!


  • 其中,搜索列表爬虫回来的内容,完全得不到歌曲id!!!

  • 解决
    解决方法也是有的!

    • python模拟浏览器
      使用selenium+phantomjs无界面浏览器,这两者的结合其实就是直接操作浏览器,可以获取JavaScript渲染后的页面数据。

    缺点:

    由于是无界面浏览器,采用此方案效率极低,如果大批量抓取不推荐。
    对于异步请求并且数据在源码中并不存在的,同时也就无法抓取到的数据。

    • 搜索的歌曲变成歌单
      比如想下载全部的某一歌手的全部音乐,用手机云音乐搜索,然后全部保存到新建一个歌单,这样就可以啦!
  • 进阶
    如果想使用了解更多网易云音乐js的加密解密过程,可以看看这个 Python 爬虫如何获取 JS 生成的 URL 和网页内容? - 路人甲的回答 - 知乎

总结

用python,就一定要简单,我认为复杂的东西,还是尽量少做,能取巧就取巧,所以本文没有使用selenium+phantomjs实践,如果想了解更多selenium+phantomjs内容,可以参考文末引用链接。

注:本文只是技术交流,请不要商业用途~ 如有违反,本人一概不负责。

全部代码

又是非常简单的100行代码完事!!!

GitHub: WebCrawlerExample/163_NeteaseMusic.py at master · iHTCboy/WebCrawlerExample


import os
import re
import json
import requests
from lxml import etree


def download_songs(url=None):
    if url is None:
        url = 'https://music.163.com/#/playlist?id=2384642500'

    url = url.replace('/#', '').replace('https', 'http')  # 对字符串进行去空格和转协议处理
    # 网易云音乐外链url接口:http://music.163.com/song/media/outer/url?id=xxxx
    out_link = 'http://music.163.com/song/media/outer/url?id='
    # 请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
        'Referer': 'https://music.163.com/',
        'Host': 'music.163.com'
    }
    # 请求页面的源码
    res = requests.get(url=url, headers=headers).text

    tree = etree.HTML(res)
    # 音乐列表
    song_list = tree.xpath('//ul[@class="f-hide"]/li/a')
    # 如果是歌手页面
    artist_name_tree = tree.xpath('//h2[@id="artist-name"]/text()')
    artist_name = str(artist_name_tree[0]) if artist_name_tree else None

    # 如果是歌单页面:
    #song_list_tree = tree.xpath('//*[@id="m-playlist"]/div[1]/div/div/div[2]/div[2]/div/div[1]/table/tbody')
    song_list_name_tree = tree.xpath('//h2[contains(@class,"f-ff2")]/text()')
    song_list_name = str(song_list_name_tree[0]) if song_list_name_tree else None

    # 设置音乐下载的文件夹为歌手名字或歌单名
    folder = './' + artist_name if artist_name else './' + song_list_name

    if not os.path.exists(folder):
        os.mkdir(folder)

    for i, s in enumerate(song_list):
        href = str(s.xpath('./@href')[0])
        song_id = href.split('=')[-1]
        src = out_link + song_id  # 拼接获取音乐真实的src资源值
        title = str(s.xpath('./text()')[0])  # 音乐的名字
        filename = title + '.mp3'
        filepath = folder + '/' + filename
        print('开始下载第{}首音乐:{}\n'.format(i + 1, filename))

        try:  # 下载音乐
            #下载歌词
            #download_lyric(title, song_id)

            data = requests.get(src).content  # 音乐的二进制数据

            with open(filepath, 'wb') as f:
                f.write(data)
        except Exception as e:
            print(e)

    print('{}首全部歌曲已经下载完毕!'.format(len(song_list)))


def download_lyric(song_name, song_id):
    url = 'http://music.163.com/api/song/lyric?id={}&lv=-1&kv=-1&tv=-1'.format(song_id)
    # 请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
        'Referer': 'https://music.163.com/',
        'Host': 'music.163.com'
        # 'Origin': 'https://music.163.com'
    }
    # 请求页面的源码
    res = requests.get(url=url, headers=headers).text
    json_obj = json.loads(res)
    lyric = json_obj['lrc']['lyric']
    reg = re.compile(r'\[.*\]')
    lrc_text = re.sub(reg, '', lyric).strip()

    print(song_name, lrc_text)




if __name__ == '__main__':
    #music_list = 'https://music.163.com/#/playlist?id=2384642500' #歌曲清单
    music_list = 'https://music.163.com/#/artist?id=8325' #歌手排行榜
    # music_list = 'https://music.163.com/#/search/m/?order=hot&cat=全部&limit=435&offset=435&s=梁静茹' #搜索列表
    download_songs(music_list)

参考


  • 如有疑问,欢迎在评论区一起讨论!
  • 如有不正确的地方,欢迎指导!


注:本文首发于 iHTCboy's blog,如若转载,请注来源

目录
相关文章
|
10天前
|
数据采集 存储 API
在信息时代,Python爬虫用于自动化网络数据采集,提高效率。
【7月更文挑战第5天】在信息时代,Python爬虫用于自动化网络数据采集,提高效率。基本概念包括发送HTTP请求、解析HTML、存储数据及异常处理。常用库有requests(发送请求)和BeautifulSoup(解析HTML)。基本流程:导入库,发送GET请求,解析网页提取数据,存储结果,并处理异常。应用案例涉及抓取新闻、商品信息等。
30 2
|
4天前
|
算法 Python
Python图论探索:从理论到实践,DFS与BFS遍历技巧让你秒变技术大牛
【7月更文挑战第11天】图论核心在于DFS与BFS。DFS深入探索,适用于找解空间;BFS逐层扩展,擅寻最短路径。
17 8
|
3天前
|
搜索推荐 Python
快速排序的 Python 实践:从原理到优化,打造你的排序利器!
【7月更文挑战第12天】Python的快速排序**以分治策略实现高效排序,平均时间复杂度$O(nlogn)$,优于$O(n^2)$的冒泡排序。基本实现通过选取基准元素分割数组,然后递归排序两部分。优化版使用随机基准避免最坏情况。对比显示优化后排序更稳定,适应不同数据集,提升程序性能。
13 4
|
4天前
|
API 开发者 Python
从理论到实践,Python asyncio库让你成为异步编程的王者!
【7月更文挑战第11天】Python的asyncio库助力异步编程,通过事件循环实现非阻塞并发。定义async函数,如`fetch_url`,用await处理异步操作。在main函数中,利用`asyncio.gather`并发执行任务。进阶应用涉及并发控制(如`asyncio.Semaphore`)和异常处理,使asyncio成为高并发场景下的得力工具。开始探索,掌握asyncio,成为异步编程专家!
14 3
|
7天前
|
数据采集 Web App开发 前端开发
Python中好用的爬虫框架
**Scrapy** 是一个强大的Python爬虫框架,适合大规模数据采集,提供高度可定制的爬取流程、内置数据提取工具、自动请求调度、分布式爬取支持、中间件扩展及多种数据存储方式。 **Beautiful Soup** 和 **Requests** 结合使用,便于Python中简单网页的请求和HTML解析。Requests发送HTTP请求,Beautiful Soup解析内容,适合小型项目或数据提取。 **Requests-HTML** 是Requests的扩展,支持HTML解析和CSS选择器,自动处理链接,适合网页解析任务。
|
7天前
|
机器学习/深度学习 数据采集 自然语言处理
Python实现循环神经网络SimpleRNN、LSTM进行淘宝商品评论情感分析(含爬虫程序)
Python实现循环神经网络SimpleRNN、LSTM进行淘宝商品评论情感分析(含爬虫程序)
Python实现循环神经网络SimpleRNN、LSTM进行淘宝商品评论情感分析(含爬虫程序)
|
9天前
|
分布式计算 NoSQL 物联网
麻省理工IOT教授撰写的1058页Python程序设计人工智能实践手册!
Python是世界上最流行的语言之一,也是编程语言中使用人数增长最快的一种。 开发者经常会很快地发现自己喜欢Python。他们会欣赏Python的表达力、可读性、简洁性和交互性,也会喜欢开源软件开发环境,这个开源环境正在为广泛的应用领域提供快速增长的可重用软件基础。 几十年来,一些趋势已经强有力地显现出来。计算机硬件已经迅速变得更快、更便宜、更小;互联网带宽已经迅速变得越来越大,同时也越来越便宜;优质的计算机软件已经变得越来越丰富,并且通过“开源”方式免费或几乎免费;很快,“物联网”将连接数以百亿计的各种可想象的设备。这将导致以快速增长的速度和数量生成大量数据。 在今天的计算技术中,最新的创新
|
12天前
|
分布式计算 NoSQL 物联网
麻省理工IOT教授撰写的1058页Python程序设计人工智能实践手册!
Python是世界上最流行的语言之一,也是编程语言中使用人数增长最快的一种。 开发者经常会很快地发现自己喜欢Python。他们会欣赏Python的表达力、可读性、简洁性和交互性,也会喜欢开源软件开发环境,这个开源环境正在为广泛的应用领域提供快速增长的可重用软件基础。
|
7天前
|
数据采集 JSON API
深入解析:抖音视频标题的Python爬虫提取方法
深入解析:抖音视频标题的Python爬虫提取方法
|
9天前
|
Python
告别混乱!Python上下文管理器的自定义实践,让你的代码更加整洁有序
【7月更文挑战第6天】Python的上下文管理器通过`__enter__`和`__exit__`方法自动处理资源的获取与释放,如文件操作。使用with语句结合自定义类(如`FileManager`示例),能确保文件在使用后正确关闭,防止资源泄漏,提升代码整洁度和健壮性。自定义上下文管理器是代码模块化和错误处理的好实践。