百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python爬虫之爬取某音乐平台(付费)歌曲

myzbx 2024-12-28 14:20 39 浏览

无意间在某站上看到一个视频,便很有兴趣地实践了起来。本篇文章仅仅是作为个人学习笔记所著,如若有所不足之处,欢迎指正。

废话不多说,先上源代码及效果图(如若对你有帮助,请阅读完本文):

网页链接:https://music.163.com/#/playlist?id=5087806619

效果图:

源代码:

# -*- codeing=utf-8 -*-
# @Time:2021/7/22 20:47
# @Atuhor:@lwtyh
# @File:批量下载.py
# @Software:PyCharm


#导入框架(库,模块)  pip install xxxx
import requests
from lxml import etree

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

# 1、确定网址   真实地址在Network----Doc
url = 'https://music.163.com/playlist?id=5087806619'
base_url = 'http://music.163.com/song/media/outer/url?id='

# 2、请求(requests) 图片,视频,音频  content     字符串 text
html_str = requests.get(url).text
# print(type(html_str))       # 字符串类型


# 3、筛选数据xpath(标签语言)

# //a[contains(@href,'/song?')]/@href

result = etree.HTML(html_str)       # 转换类型
# print(type(result))
song_ids = result.xpath('//a[contains(@href,"/song?")]/@href')   # 歌曲id
song_names = result.xpath('//a[contains(@href,"/song?")]/text()')       # 歌名

# print(song_ids)
# print(song_names)     #列表


# 对列表进行解压
i = 0       # 按顺序来
for song_id,song_name in zip(song_ids,song_names):
    # print(song_id)
    # print(song_name)
    count_id = song_id.strip('/song?id=')   # 去掉/song?id=
    # print(count_id)

    # 过滤含有“$”符号
    if ('#39; in count_id) == False:
        # print(count_id)
        song_url = base_url + count_id      # 拼接url
        # print(song_url)

        i += 1

        mp3 = requests.get(song_url).content

        # 4、保存数据
        with open('./yinyue/{}.{}.mp3'.format(i,song_name),'wb') as file:
            file.write(mp3)


目的:

一张截图,请自行分析:


这是一张再熟悉不过的图片了,想要获取本页面这些音乐,方法很多,如APP内自行下载啥的,但是,本次我想利用所学到的一点皮毛进行下载。

我们都知道,对于网页上的音乐在进行下载时,经常会弹出如下页面:


好好的下载一首歌曲,非要弄得这么麻烦。甚至,有些音乐在下载了软件后,需要付费或者VIP,让人很是苦恼。更严重者,好不容易下载好了,却发现格式不对等种种情况,让人崩溃。

为此我们可以很好地通过简单的爬虫解决以上问题。

对网页进行分析:

1. 在一开始,本人给出了本网页的链接:https://music.163.com/#/playlist?id=5087806619但是细心的小伙伴会发现,在代码中所使用的的网址并非是这个:

url = 'https://music.163.com/playlist?id=5087806619'


这是因为我们所请求的网址并非是浏览器地址栏上的网址,通过这张截图,很清晰地发现我们所请求的网址是哪个了。(
这是一个很重要的点,必须学会分析。

2. 通过对每首歌曲打开,进行网页源代码分析不难发现,本网页的10首歌曲都有一个共同的特点:即https://music.163.com/#/song?id=1475436266
前面的网址为
https://music.163.com/#/song?id= 加每首歌曲的 id 好,这很简单。


3. 然而,我们永远想得过于简单了,到目前为止,我们仅仅是找到了些许规律,但是要真正下载到每一首歌曲,还遥不可及。
因为我们进行了这么久的分析,并没有找到歌曲的真正链接。


通过对这些内容的查找,我们是可以说,根本就无法找到音乐文件(MPEG、MP3、MPEG-4、MIDI、WMA、M4A等)。

那是我们到现在为止还没有请求音乐,而当我们在进行点击播放时会发现如下图所示(与上图进行比较)发现:

  • 该网页的请求数量由原来的167一下增加至192,这就证明,当我们在进行播放音乐时,该网页又重新进行了对网页的请求。
  • 其次,通过重新查找发现(只需查看后面新的内容)这次有了一些 .m4a 文件。
  • 当点击这些文件打开时会发现,有一个新的 Request URL:,当你将该网址复制在新的网页下进行打开,会出现如下图所示(打开时浏览器会自动进行下载该音乐):
    或者: 像下图所示,会出现该音频,当你浏览器跟迅雷下载器所绑定,会立马弹出迅雷界面,进行该音乐的下载。
    结合上面的情况来说,我们是不是已经成功了呢?但很难过地告诉你,这个网址在短时间内打开,的确会有用,但是,它是有时间限制的,不信的话,你可以过五分钟(或许还不需要这么久)再重新打开该网址,试一下。

那么,照我这么一说,没办法了吗?当然不是,办法还是有的,不然,怎么敢在此“放肆”呢?

问题解决:

通过之前对网页进行分析,我们正一步一步地进行了解、熟悉,且到最后,我们甚至找到了歌曲的最终URL,但是可惜的是,该URL并非是一个永久的,只是一个短暂、临时的动态URL,这简直给我们泼了一盆冷水。
然而,我们无需灰心,俗话说 “
魔高一尺,道高一丈 ”,办法还是有的。

需将这个问题解决,不得不介绍一个新的URL:

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

在这里,就不卖关子了,这是一个该平台(至于是什么平台,你懂得)的外部链接。在之前的分析中,我们发现了一个很重要的一点,便是这10首歌曲都是一个网址加每首歌曲的id所在的新页面。

在代码中你也会发现所使用的 base_url 便是这个链接。

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

也就是说,我们有了上面的这个网址,便可以为所欲为了。爱动手的你现在便可以立马复制上面的链接,在网页上找到一首歌曲的id号添加至网址后面进行打开(如:http://music.163.com/song/media/outer/url?id=1822734959),是不是得到了如下的界面:


是不是很熟悉呢?没错,这就是之前我们利用网页分析得到的网址所打开的网页,很可惜的是之前那网址是一个临时、动态的网址,对于我们来说进行批量下载没多大用处。所以,当我们现在有了这个新网址,就方便了很多。

好,想一想,既然我们有了这么一个神奇的网址,接下来,该干嘛了呢?好好想一下。

正片开始:

在经过了前面两大点的分析,现在我们可以游刃有余地对这十首音乐进行爬取了。
相信,很多人都知道接下来一步该干什么了吧?

每首音乐可以通过 http://music.163.com/song/media/outer/url?id= 这个网址加每首音乐的 id 进行下载,所以,我们第一步便是想办法获取每首音乐的 id


通过之前的这张图不难发现,每首音乐的
id 都在一个a标签内。

#导入框架(库,模块)  pip install xxxx
import requests

# 1、确定网址   真实地址在Network----Doc
url = 'https://music.163.com/playlist?id=5087806619'

# 2、请求(requests) 图片,视频,音频  content     字符串 text
html_str = requests.get(url).text
print(html_str)
print(type(html_str))       # 字符串类型

便可以通过上述代码,先将该网页的源代码进行爬取下来,再进行分析。

在这里使用多加了一横打印该页代码的数据类型,不难发现所打印出来的类型为 字符串 。这便有了后续需要将该内容转换为 _Element对象

>>>result = etree.HTML(html_str)       # 转换类型
>>>print(type(result))
class 'lxml.etree._Element'>		#输出类型

作为_Element对象,可以方便地使用getparent()、remove()、xpath()等方法。

而此次爬虫,恰恰所使用的的便是 xpath() 方法。

所以,还需要导入一个新的模块,即:

from lxml import etree


通过浏览器的
XPath Helper 插件可以快速地匹配到每首音乐的 id

song_ids = result.xpath('//a[contains(@href,"/song?")]/@href')   # 歌曲id
song_names = result.xpath('//a[contains(@href,"/song?")]/text()')       # 歌名
print(song_ids)
print(song_names)     #列表

而当我们打印出来时,却发现这是一个列表类型。不着急,可以借用 for 进行快速遍历:

for song_id,song_name in zip(song_ids,song_names):
    print(song_id)
    print(song_name)


通过打印发现,前面多了一些
/song?id= ,这时,便使用下面这行代码,进行删减:

count_id = song_id.strip('/song?id=')   # 去掉/song?id=

歌名没有进行打印了,因为我们主要是获取每首音乐的 id ,然而,仔细看上图发现后面多了三个无用的,这三个必须删掉才行,不然在进行后面的 URL 拼接,肯定会报错,因为压根就找不到这样的一个网址。便有了后面的判断语句。

# 过滤含有“$”符号
    if ('#39; in count_id) == False:
        print(count_id)

清一色id号:


接下来便是拼接新的URL:

song_url = base_url + count_id      # 拼接url
       print(song_url)

在浏览器里打开上面的任意链接,即可获取该音乐的链接,并进行下载。
但是,我们最终的目的肯定不在于此,而是让爬虫自动帮我们全部下载并进行保存至文件夹。

mp3 = requests.get(song_url).content

所以,我们便进行请求网址,获取每首音乐。最后,在进行保存即可。

# 4、保存数据
with open('./yinyue/{}.{}.mp3'.format(i,song_name),'wb') as file:
	file.write(mp3)

需要注意的是,源代码中本人在 for 进行遍历时,增加了一个变量 i ,这是为了我们所爬取下来的音乐保存在文件夹的顺序还是如网页中的顺序所一样,当然如若不需要可将其删除。

到现在看来,我们爬取到了这歌单中的10首音乐,那试想一下,获取其它歌单中的音乐是不是也可以用相同的方法进行获取呢?爱动手的你,快去试一试吧!实践出真知!

说在最后的话:

  1. 学无止境。利用写博客的方式将所学内容进行一遍温习,加深自己的印象,强化学习。
  2. 同时,写出来的每一篇笔记为大家作参考,也欢迎各位大佬进行指点,相互交流学习。
  3. 如若侵权,联系即删!

相关推荐

别让水 “跑” 出卫生间!下沉设计打造滴水不漏的家

你是否遭遇过卫生间的水“偷偷溜”进客厅,导致木地板鼓起、墙角发霉的糟心事?又是否为卫生间门口反复渗漏,不得不一次次返工维修而头疼不已?在家庭装修中,卫生间防水堪称“兵家必争之地”,而卫生间门口下...

歼-10CE vs 阵风:谁才是空中霸主?全面性能对比解析

歼10CE与法国阵风战斗机性能深度对比分析一、总体定位与设计哲学歼10CE:单发中型多用途战斗机,侧重于空优(制空权争夺)和对地对海打击,具有较高的性价比和较强的多任务能力。法国阵风战斗机:双发中型多...

知名移植工作室肯定Switch2的图形性能,却被CPU拖了后腿

虽然Switch2发售多日,但没入手的玩家对其性能还是有顾虑。近日,知名移植工作室Virtuos的技术总监在接受采访时讨论了Switch2的性能,并给出了他们工作室的评价。简单来说,Switch2在D...

虹科实测 | CAN XL vs CAN FD传输性能深度对比:速率翻倍,抖动锐减!

导读在汽车电子与工业通信领域,CAN协议持续进化,推动着数据传输效率的提升。本次实测基于虹科PCAN-USBXL与虹科PCAN-USBProFD硬件,在同等严苛条件下对比CANXL与CANF...

1J117合金材料优异的耐腐蚀性、机械性能

1J117合金材料概述定义:1J117是一种不锈软磁精密合金,属于铁铬基合金,其圆棒产品具有特定的形状和尺寸,可满足各种工业应用中的特定需求。标准:技术条件标准为GB/T14986,品种规格标准...

据高管所称,Switch2能轻松移植XSS平台60帧游戏

任天堂,作为主机游戏界的御三家之一,一直注重游戏性而不注重更新升级硬件设备是其最大的特点。各位任豚们,忍受着任天堂早已落后硬件设备,真想感叹一句,天下苦任久矣!但Switch2的出现或许正在渐渐的改变...

FJK-110LED-HXJSN磁传感器有哪应用

作为一名从事电子技术相关工作的自媒体人,我经常会遇到各种传感器的应用问题。其中,FJK-110LED-HXJSN磁传感器是一款在工业自动化、智能设备等领域比较常见的磁场检测元件。今天我想和大家聊一聊这...

浅谈欧标方管200x200x5-12mm质S275JRH的优势与劣势

欧标方管200x200x5-12mm材质S275JRH是一种常见的结构用钢材,广泛应用于建筑、机械制造、桥梁、钢结构等领域。本文将对这种方管的优势与劣势进行浅谈,以帮助读者更好地了解其特性和适用场景。...

宽带拨号错误 651 全解析:故障定位与修复方案

在使用PPPoE拨号连接互联网时,错误651提示「调制解调器或其他连接设备报告错误」,通常表明从用户终端到运营商机房的链路中存在异常。以下从硬件、系统、网络三层维度展开排查:一、故障成因分类图...

模型微调:从理论到实践的深度解析

在人工智能领域,模型微调已成为提升模型性能、使其适应特定任务的关键技术。本文将全面系统地介绍模型微调的各个方面,帮助读者深入理解这一重要技术。一、什么是模型微调模型微调是指在已经训练好的预训练模型基础...

汉语拼音 z、c、s图文讲解(拼音字母表zcs教学视频)

以下是汉语拼音z、c、s的图文讲解,结合发音要领、书写规范及教学技巧:一、发音方法与口诀1.z的发音发音要领:舌尖轻抵上齿背,形成阻碍后稍放松,气流从窄缝中挤出,声带不振动(轻短音)。口诀:“写字写...

吴姗儒惹怒刘宇宁粉丝!吴宗宪护航「是综艺梗」叮咛女儿对话曝光

记者孟育民/台北报道Sandy吴姗儒在《小姐不熙娣》因为节目效果,将男星刘宇宁的头像踩在地上,引起粉丝怒火,节目发声明道歉后仍未平息,她也亲自发文郑重道歉:「我对刘宇宁本人完全没有任何恶意,却在综艺表...

苹果错误地发布了macOS Tahoe公开测试版 现已将其撤下

一些Beta测试人员下载了他们以为是macOSSequoia15.6RC的版本,但却错误地下载了macOSTahoe26公开测试版,后来苹果修复了该问题。苹果预计将于7月25...

make的多种用法!(make 的用法总结)

一、make的用法美make[meik]①V.制造;制定,拟定;使变得,使处于;造成,引起;整理(床铺);做,作出;强迫;挑选,任命…②n.(机器、设备等的)品牌,型号;结构,构造;通电,接电⑤[...

北顿尖刀哗变?俄第20近卫集团军损失惨重,拒绝执行指挥官命令?

【军武次位面】作者:太白近日,外国社交媒体“电报”上传出了一些消息,称俄罗斯在北顿涅兹克战场上的“尖刀”部队之一,俄第20近卫集团军因为损失惨重,已经出现了部分部队拒绝执行指挥官命令,甚至哗变的情况。...