天涯论坛

 找回密码
 立即注册
搜索
查看: 15|回复: 0

Python爬虫实践--爬取网易云音乐

[复制链接]

3138

主题

3万

回帖

9996万

积分

论坛元老

Rank: 8Rank: 8

积分
99968624
发表于 2024-10-26 16:48:53 | 显示全部楼层 |阅读模式

前言

近期,网易的音乐非常多听不到了,刚好看到非常多教程,跟进学习了一下,集大全了吧,本来想优化一下的,然则发掘问题还是有点繁杂,最后另辟捷径,供给了简单的办法啊!

Python + 爬虫

首要,说一下准备工作:

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

json:python的json处理库

而后,说一下此刻已然晓得下载链接是这般的:
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 就能够了,不必爬虫啊!

下载歌词

倘若还要下载歌词,那很简单,经过接口,有歌曲的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 }

坑点与进阶

表面上很简单,然则需要重视的是,网易返回的链接,数据是js动态加载,便是爬虫得到的网页数据和浏览器得到的dom内容和结构不同样

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

处理

处理办法是有的!

python模拟浏览器

运用selenium+phantomjs无界面浏览器,这两者的结合其实便是直接操作浏览器,能够获取JavaScript渲染后的页面数据。

缺点

因为是无界面浏览器,采用此方法效率极低,倘若大批量抓取不举荐

针对异步请求并且数据在源码中并不存在的,同期没法抓取到的数据。

搜索的歌曲变成歌单

例如想下载所有的某一歌手的所有音乐,用手机云音乐搜索,而后所有保留到新建一个歌单,这般能够啦!

总结

用python,就必定要简单,我认为繁杂的东西,还是尽可能少做,能取巧就取巧,因此本文运用selenium+phantomjs实践。

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

所有代码

又是非常简单的100行代码完事!!! import os import re importjsonimport 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 inenumerate(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)

如有疑问,欢迎在评论区一块讨论!

如有不正确的地区,欢迎指点




上一篇:Python爬虫教程,爬取网易云的音乐
下一篇:打击违法信息外链!中央网信办出手!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|天涯论坛 ( 非经营性网站 )|网站地图

GMT+8, 2024-11-23 08:56 , Processed in 0.283034 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.