从歌曲网站,获取音频和歌词的流程:

  • 1, 输入歌曲名,查找网站中存在的歌曲 id

  • 2, 拿歌曲 id 下载歌词 lyric

简单的 url 拼接

  • 3, 拿歌曲 id 下载音频 mp3

先用一个 POST 请求,拿 ID 取音频资源路径,

再用 GET 请求,拿到音频资源

4 个网络请求,解决,

搜索歌曲,获取歌词,获取音频资源路径,获取音频资源

注意的是,4 个网络请求,都要模拟正常的浏览器请求,

  • GET 请求,需要配置请求头,

  • POST 请求,需要配置请求头和请求体

1, 查找网站的歌曲

先准备,模拟正常的浏览器请求

配置 Session,

有一个加解密,具体见 github repo.

def __init__(self, timeout=60, cookie_path='.'):
self.headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded',
'Host': 'music.x.com',
'Referer': 'http://music.x.com/search/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
self.session = requests.Session()
self.session.headers.update(self.headers)
self.session.cookies = cookiejar.LWPCookieJar(cookie_path)
self.download_session = requests.Session()
self.timeout = timeout
self.ep = Encrypyed()

封装 Post 请求方法


def post_request(self, url, params):
"""
Post请求
:return: 字典
""" data = self.ep.encrypted_request(params)
resp = self.session.post(url, data=data, timeout=self.timeout)
result = resp.json()
if result['code'] != 200:
click.echo('post_request error')
else:
return result

去搜索:

    def search(self, search_content, search_type, limit=9):
"""
搜索API
:params search_content: 搜索内容
:params search_type: 搜索类型
:params limit: 返回结果数量
:return: 字典.
""" url = 'http://music.x.com/weapi/xxx/get/web?csrf_token='
params = {'s': search_content, 'type': search_type, 'offset': 0, 'sub': 'false', 'limit': limit}
result = self.post_request(url, params)
return result

拿到搜索结果:


result = self.search(song_name, search_type=1, limit=limit) if result['result']['songCount'] <= 0:
click.echo('Song {} not existed.'.format(song_name))
else:
songs = result['result']['songs']
if quiet:
song_id, song_name = songs[0]['id'], songs[0]['name']
song = Song(song_id=song_id, song_name=song_name, song_num=song_num)
return song

下载歌词

下载很简单

        lyricUrl = 'http://music.x.com/api/song/lyric/?id={}&lv=-1&csrf_token={}'.format(song_id, csrf)
lyricResponse = self.session.get(lyricUrl)

拿到一个 json ,获取里面的歌词,

        lyricJSON = lyricResponse.json()
lyrics = lyricJSON['lrc']['lyric'].split("\n")
lyricList = []
for word in lyrics:
time = word[1:6]
name = word[11:]
p = Node(time, name)
lyricList.append(p)
json_string = json.dumps([node.__dict__ for node in lyricList], ensure_ascii = False, indent = 4)

写入新建的本地文件

        if not os.path.exists(folder):
os.makedirs(folder)
fpath = os.path.join(folder, str(song_num) + '_' + song_name + '.json')
text_file = open(fpath, "w")
n = text_file.write(json_string)
text_file.close()

下载音频分两步

  • 先拿到音频资源路径
        url = 'http://music.x.com/weapi/song/enhance/player/url?csrf_token='
csrf = ''
params = {'ids': [song_id], 'br': bit_rate, 'csrf_token': csrf}
result = self.post_request(url, params)
# 歌曲下载地址
song_url = result['data'][0]['url'] # 歌曲不存在
if song_url is None:
click.echo('Song {} is not available due to copyright issue.'.format(song_id))
else:
return song_url
  • 再获取音频资源
        if not os.path.exists(fpath):
resp = self.download_session.get(song_url, timeout=self.timeout, stream=True)
length = int(resp.headers.get('content-length'))
label = 'Downloading {} {}kb'.format(song_name, int(length/1024))

一边下载,一边看进度

           with click.progressbar(length=length, label=label) as progressbar:
with open(fpath, 'wb') as song_file:
for chunk in resp.iter_content(chunk_size=1024):
if chunk:
song_file.write(chunk)
progressbar.update(1024) 交流基地:630390733

歌曲网站,教你爬取 mp3 和 lyric的更多相关文章

  1. Python_记一次网站数据定向爬取实现

    记一次网站数据定向爬取实现 by:授客 QQ:1033553122 测试环境: Python版本:Python 3.4 Win7 请勿用于商业及非法用途,仅供学习研究用,否则后果自负 数据爬取场景 如 ...

  2. 一个免费ss网站的数据爬取过程

    一个免费ss网站的数据爬取过程 Apr 14, 2019 引言 爬虫整体概况 主要功能方法 绕过DDOS保护(Cloudflare) post中参数a,b,c的解析 post中参数a,b,c的解析 p ...

  3. Python爬虫:设置Cookie解决网站拦截并爬取蚂蚁短租

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Eastmount PS:如有需要Python学习资料的小伙伴可以加 ...

  4. py3+urllib+bs4+反爬,20+行代码教你爬取豆瓣妹子图

    0.准备 所用到的模块: urllib.request,获取源码 beautifulsoup4(bs4),网页抓取数据   安装bs4,python3 -m pip install beautiful ...

  5. 50 行代码教你爬取猫眼电影 TOP100 榜所有信息

    对于Python初学者来说,爬虫技能是应该是最好入门,也是最能够有让自己有成就感的,今天,恋习Python的手把手系列,手把手教你入门Python爬虫,爬取猫眼电影TOP100榜信息,将涉及到基础爬虫 ...

  6. nodejs实现网站数据的爬取

    // 引入https模块,由于我们爬取的网站采用的是https协议 const https = require('https'); // 引入cheerio模块,使用这个模块可以将爬取的网页源代码进行 ...

  7. Python爬虫: "追新番"网站资源链接爬取

    “追新番”网站 追新番网站提供最新的日剧和日影下载地址,更新比较快. 个人比较喜欢看日剧,因此想着通过爬取该网站,做一个资源地图 可以查看网站到底有哪些日剧,并且随时可以下载. 资源地图 爬取的资源地 ...

  8. 教你爬取腾讯课堂、网易云课堂、mooc等所有课程信息

    本文的所有代码都在GitHub上托管,想要代码的同学请点击这里

  9. 中国农产品信息网站scrapy-redis分布式爬取数据

    ---恢复内容开始--- 基于scrapy_redis和mongodb的分布式爬虫 项目需求: 1:自动抓取每一个农产品的详细数据 2:对抓取的数据进行存储 第一步: 创建scrapy项目 创建爬虫文 ...

随机推荐

  1. 这些鲜为人知的前端冷知识,你都GET了吗?

    背景 最近公司项目不多,比较清闲,划水摸鱼混迹于各大技术博客平台,瞬间又GET了好多前端技能,一些属于技巧,一些则是闻所未闻的冷知识,一时间还消化不过来,不由的发出一声感叹! 前端可真是博大精深 于是 ...

  2. 【刷题笔记】DP优化-状压

    因为篇幅太长翻着麻烦,计划把DP拆成几个小专题,这里原文只留下状压,其他请至后续博文. 状态压缩优化 所谓状态压缩,就是将原本需要很多很多维来描述,甚至暴力根本描述不清的状态压缩成一维来描述. 时间复 ...

  3. 新手上路之如何选择Java版本

    @ 目录 LTS与非LTS LTS 非LTS Java CPU与PSU Java SE.Java EE.Java ME的区别 Java SE Java EE Java ME 每一次JDK上新总有一群人 ...

  4. Spark SQL解析查询parquet格式Hive表获取分区字段和查询条件

    首先说一下,这里解决的问题应用场景: sparksql处理Hive表数据时,判断加载的是否是分区表,以及分区表的字段有哪些?再进一步限制查询分区表必须指定分区? 这里涉及到两种情况:select SQ ...

  5. 色相偏移 HueShift ASE

    色相偏移可以改变颜色色调,unity ASE没有参考UE4写个,原理很简单,将颜色向量绕(1,1,1)旋转,就可以得到不同色调的颜色. https://zhuanlan.zhihu.com/p/677 ...

  6. MySQL——一致性非锁定读(快照读)&MVCC

    MySQL--一致性非锁定读(快照读) MySQL数据库中读分为一致性非锁定读.一致性锁定读 一致性非锁定读(快照读),普通的SELECT,通过多版本并发控制(MVCC)实现. 一致性锁定读(当前读) ...

  7. Python中排序方法sort、函数sorted的key参数的作用分析

    从Python2.4开始,list.sort方法 和 sorted方法 都增加了一个 'key' 参数用来在进行比较之前指定每个列表元素上要调用的函数,将函数的返回值作为比较的依据. 那么怎么使用这个 ...

  8. 转2:Python字符编码详解

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...

  9. Python正则表达式处理中的匹配对象是什么?

    老猿才开始学习正则表达式处理时,对于搜索返回的匹配对象这个名词不是很理解,因此在前阶段<第11.3节 Python正则表达式搜索支持函数search.match.fullmatch.findal ...

  10. PyQt(Python+Qt)学习随笔:QListView的spacing属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QListView的spacing属性用于控制视图布局中数据项周围填充的空白空间的大小.缺省值为0, ...