Python爬⾍实践--爬取⽹易云⾳乐
Python爬⾍实践
前⾔
最近,⽹易的⾳乐很多听不到了,刚好也看到很多教程,跟进学习了⼀下,也集⼤全了吧,本来想优化⼀下的,但是发现问题还是有点复杂,最后另辟捷径,提供了简单的⽅法啊!
Python + 爬⾍
⾸先,说⼀下准备⼯作:
Python:需要基本的python语法基础
requests:专业⽤于请求处理,requests库学习⽂档中⽂版
lxml:其实可以⽤python⾃带的正则表达式库re,但是为了更加简单⼊门,⽤ lxml 中的 etree 进⾏⽹页数据定位爬取。
re:python正则表达式处理
json:python的json处理库
然后,说⼀下现在已经知道下载链接是这样的:
music.163/song/media/outer/url?id='
山西 旅游id 就是歌曲的id!
所以,现在我们爬⾍主要的⼯作就是到这个id,当然为了更好的保存,也要到这个歌名啦!
那现在就是要到我们需要爬⾍的⽹站链接啦!我分析了⼀下,⼤概是下⾯三种:
#歌曲清单
music_list ='music.163/#/playlist?id=2412826586'
#歌⼿排⾏榜
artist_list ='music.163/#/artist?id=8325'
埃及的传说#搜索列表
国庆法定几天search_list ='music.163/#/search/m/?order=hot&cat=全部&limit=435&offset=435&s=梁静茹'
铰链结构下载歌词
如果还要下载歌词,那也很简单,通过接⼝,有歌曲的id就可以:
url ='music.163/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,就⼀定要简单,我认为复杂的东西,还是尽量少做,能取巧就取巧,所以本⽂没有使⽤sel
enium+phantomjs实践。
注:本⽂只是技术交流,请不要商业⽤途~ 如有违反,本⼈⼀概不负责。
全部代码
⼜是⾮常简单的100⾏代码完事
import os
import re
import json
import requests
from lxml import etree
def download_songs(url=None):
if url is None:
url ='music.163/#/playlist?id=2384642500'
url = place('/#','').replace('https','http')# 对字符串进⾏去空格和转协议处理
# ⽹易云⾳乐外链url接⼝:music.163/song/media/outer/url?id=xxxx
out_link ='music.163/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':'music.163/',
'Host':'music.163'
}
# 请求页⾯的源码
res = (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 ists(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 = (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 ='music.163/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':'music.163/',
'Host':'music.163'
# 'Origin': 'music.163'
}
# 请求页⾯的源码
res = (url=url, headers=headers).text
json_obj = json.loads(res)
lyric = json_obj['lrc']['lyric']
reg = repile(r'\[.*\]')
lrc_text = re.sub(reg,'', lyric).strip()
print(song_name, lrc_text)
if __name__ =='__main__':
#music_list = 'music.163/#/playlist?id=2384642500' #歌曲清单
music_list ='music.163/#/artist?id=8325'#歌⼿排⾏榜
# music_list = 'music.163/#/search/m/?order=hot&cat=全部&limit=435&offset=435&s=梁静茹' #搜索列表
download_songs(music_list)
如有疑问,欢迎在评论区⼀起讨论!
如有不正确的地⽅,欢迎指导!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论