网易云下载音乐后续
网易云下载音乐
后续
本篇阅读时间约为 6 分钟。
1
前言
本篇文章,承接一星期之前写的的网易云音乐后续。当时思路给大家了,不知道自己动手的有多少人?动手才有收获呀~
今天给大家介绍一下笔者是如何写源码思路的。
网易云歌曲具体思路回顾:还在用网易云音乐客户端?out了~
2
网易云核心代码思路讲解
爬虫的重点在于分析思路,代码实现千万种,笔者这里简单的介绍下自己的核心代码思路(用中文写逻辑,俗称“伪代码”),至于具体源码,详见文末。
本次用到的第三方库分别是 requests 、beautifulsoup4 库。所以如果你想模拟代码运行,确保有此两个库。仔细看过笔者之前写过文章的朋友们,一定知道 Pypi 这个网站,才给大家说下,如何去找第三方库。
百度搜索 Pypi ,第一个网站就是,点开后,直接搜索相应的库名即可,点进去:
pip install beautifulsoup4
requests 库,同理:
pip install requests
1. 模拟请求到网易云,缓存 HTML 源代码
此过程中源码对应的是 __crawl_html() ,使用了 requests 库,在 Python 小课堂中,笔者曾经使用 urllib 这个原生库模拟浏览器爬取熊猫TV。今天推荐的是 Python 届最好用,最人性化的请求库,即 requests 。
使用方法非常简单,一行代码即可实现模拟登陆,具体操作,大家可以自行查看官方文档。搜索,requests库中文官方文档,第一个就是。
笔者一直在强调,新学习一个东西,最快、最有效、最不被误导的做法就是去看官方文档。
在笔者的源代码中,使用 requests 模拟请求时,做了一层本地缓存,将服务端的源码写到了本地磁盘中,便于多次调试,不用每一次都访问网易云网页,如果本地有 html 文件的源代码,直接读取即可.
2. 解析歌曲相关信息节点,yield关键字返回
此过程中源码对应的是 __analysis_node() ,其中使用了 beautifulsoup 库,它的作用是将你的HTML源代码,以一种指定的解析器进行解析,源码中我使用的是 lxml 解析器,lxml也是第三方库,需要单独安装。快速上手,自己去查阅官方文档,下面举个例子:
使用方法有点像正则,举个小例子:
from bs4 import BeautifulSoup as bs
soup = bs(html, 'lxml')
soup.find(name='ul', attrs={'class': 'f-hide'})
在网上,经常有人说,bs(html,'lxml') 实例化对象时,就像做出“一锅美味的汤”,接下来,你需要对这个“汤”,也就是 soup 进行操作。
soup.find() 中,name就是 html 的标签名称,attrs 是属性的简写,所以,上面的例子中的意思就是,查询出这样的节点:
<ul class = "f-hide">
但是我们需要获取的是歌曲 id ,id的分析去看上一篇中,它是在 ul 下的 li 下的 a 标签中的 href 的内容,代码如下:
ul_node = soup.find(name='ul', attrs={'class': 'f-hide'}) # 获取歌曲id的ul
li_node = ul_node.find_all(name='li')
for a_node in li_node:
href_content = a_node.find(name='a').get('href') # 超链接
song_name = a_node.find(name='a').get_text()
yield {
'href_content': href_content,
'song_name': song_name
}
最终将所有匹配的信息,用 yield 关键词返回。yield 的用途是将此函数作为生成器,在调用此函数的时候,才会开始计算返回。
生成器不熟悉的,回顾:python小课堂34 - 推导式与生成器
3. 获取到 id,可以对id进行拼接下载
此过程中源码对应的是 __downloader() ,对相关信息进行数据清洗,然后拼接下载地址,继续使用 requests 模拟请求:
mp3_stream = requests.get(url=mp3_url, headers=self.headers).content
mp3_file_name = f'{self.song_list_name}/{song_name}.mp3' # mp3文件名字
self.write_file(mp3_file_name, 'wb', mp3_stream) # 二进制写入
random_time = random.random()
print(f'第{self.count}首下载完成...歌名:{song_name},随机休眠{random_time}s...\n')
time.sleep(random_time)
其中,requests.content ,是将文件以二进制流获取,只需将流写入本地,存成 mp3 格式即可。在最后,加上了随机休眠机制,缓慢请求!控制速度~
调用 downloader 时,用了一个 map() 函数,python 的高阶函数,因为设计 downloader 时,按照单一职责制定的,每次 downloader 中只处理一首歌,而不是在 downloader 中去 for 循环遍历。
3
结语
在学习本篇文章时,建议看源代码的同时,结合文章一起观看,效果更佳。
本篇设计角度是从工程性出发,若读者们有不同的设计观点,欢迎探讨!
如需源码,老规矩,后台回复:网易云 ,即可获得!
至此完!
长按关注
公众号名称:咪哥杂谈
一个咪咪怪的公众号
长按二维码关注哦!