要爬取的网站入口链接如下:
http://music.taihe.com/#songlist/365365950?fr=shoubai&noad=1
爬取的简单思路:
1、通过抓包分析可以看出每一首歌曲的真实链接主要由三部分组成
“64f52b8d12bfe21117c45f19c44472ec”这一串字符表示的是Etag,这里简单解释一下Etag的作用:
ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,它是用作缓存使用的两个主要的头信息之一 (另一个是Expires),ETag一般不以明文形式相应给客户端。在资源的各个生命周期中,它都具有不同的值,用于标识出资源的状态。当资源发生变更时,如果其头信息中一个或者多个发生变化,或者消息实体发生变化,那么ETag也随之发生变化。
"594519531"表示歌曲的ID;
"b166454c49fd09deed47f60d337fa3fd"为xcode代码,根据这些代码服务器返回给你该MP3文件。
2、经过简单分析之后,发现这三部分都是由JS动态生成,自己无法构造拼接,所以继续抓分析,知道找到了songlink这个东东
打开一看,只要给这个链接post一个歌曲请求ID即可得到这首歌曲的详细信息(包括歌曲的时长、xcode、歌词链接、歌曲链接等),这样就不需要自己构造MP3链接了,而歌曲的请求ID网站入口输入歌曲名称后用xpath就很容易获得了。
"http://play.taihe.com/data/music/songlink?songIds="+songId(拼接上歌曲的请求链接)
3、下面上代码
import json
import os
import requests
from lxml import etree
#获取歌曲ID
def getSongsid(songName):
pageUrl="http://music.taihe.com/search?key="+songName
pageHtml=requests.get(pageUrl)
# 解析html页面
selector=etree.HTML(pageHtml.text)
# 通过xpath获取歌曲ID
songId=selector.xpath('//*[@id="first_song_li"]/div/span[4]/a/@href')[0][6:]
getSongsInfo(songId,songName)
# 获取歌曲的详细信息(主要是获取歌曲的真实MP3链接和歌词链接)
def getSongsInfo(songId,songName):
songsInfo="http://play.taihe.com/data/music/songlink?songIds="+songId
# 获取歌曲的详细信息(json格式)
songsJsons=requests.get(songsInfo)
#解析json格式的数据
dataJson=json.loads(songsJsons.text)
#歌曲的歌词链接
songsLrc=dataJson['data']["songList"][0]["lrcLink"]
#歌曲的真实MP3链接
songsMp3=dataJson['data']["songList"][0]["songLink"]
downSongs(songsMp3,songName)
# 开始下载歌曲
def downSongs(songsUrl,songName):
dataMp3=requests.get(songsUrl)
path="E://"+songName+".mp3"
if not os.path.exists(path):
with open(path,"wb") as f:
f.write(dataMp3.content)
f.close()
print("下载完毕")
if __name__=="__main__":
songName=input("请输入您要下载的歌曲名称:")
getSongsid(songName)