All Projects → yangjianxin1 → Qqmusicspider

yangjianxin1 / Qqmusicspider

基于Scrapy的QQ音乐爬虫(QQ Music Spider),爬取歌曲信息、歌词、精彩评论等,并且分享了QQ音乐中排名前6400名的内地和港台歌手的49万+的音乐语料

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Qqmusicspider

Scrapyrt
HTTP API for Scrapy spiders
Stars: ✭ 637 (+430.83%)
Mutual labels:  crawler, scrapy
Terpene Profile Parser For Cannabis Strains
Parser and database to index the terpene profile of different strains of Cannabis from online databases
Stars: ✭ 63 (-47.5%)
Mutual labels:  crawler, scrapy
Py3 scripts
Life is short, *****.
Stars: ✭ 5 (-95.83%)
Mutual labels:  crawler, scrapy
Filemasta
A search application to explore, discover and share online files
Stars: ✭ 571 (+375.83%)
Mutual labels:  crawler, music
Dotnetcrawler
DotnetCrawler is a straightforward, lightweight web crawling/scrapying library for Entity Framework Core output based on dotnet core. This library designed like other strong crawler libraries like WebMagic and Scrapy but for enabling extandable your custom requirements. Medium link : https://medium.com/@mehmetozkaya/creating-custom-web-crawler-with-dotnet-core-using-entity-framework-core-ec8d23f0ca7c
Stars: ✭ 100 (-16.67%)
Mutual labels:  crawler, scrapy
Easy Scraping Tutorial
Simple but useful Python web scraping tutorial code.
Stars: ✭ 583 (+385.83%)
Mutual labels:  crawler, scrapy
Crawlab
Distributed web crawler admin platform for spiders management regardless of languages and frameworks. 分布式爬虫管理平台,支持任何语言和框架
Stars: ✭ 8,392 (+6893.33%)
Mutual labels:  crawler, scrapy
Haipproxy
💖 High available distributed ip proxy pool, powerd by Scrapy and Redis
Stars: ✭ 4,993 (+4060.83%)
Mutual labels:  crawler, scrapy
Scrapoxy
Scrapoxy hides your scraper behind a cloud. It starts a pool of proxies to send your requests. Now, you can crawl without thinking about blacklisting!
Stars: ✭ 1,322 (+1001.67%)
Mutual labels:  crawler, scrapy
Taiwan News Crawlers
Scrapy-based Crawlers for news of Taiwan
Stars: ✭ 83 (-30.83%)
Mutual labels:  crawler, scrapy
Wechatsogou
基于搜狗微信搜索的微信公众号爬虫接口
Stars: ✭ 5,220 (+4250%)
Mutual labels:  crawler, scrapy
Patentcrawler
scrapy专利爬虫(停止维护)
Stars: ✭ 114 (-5%)
Mutual labels:  crawler, scrapy
Fbcrawl
A Facebook crawler
Stars: ✭ 536 (+346.67%)
Mutual labels:  crawler, scrapy
Icrawler
A multi-thread crawler framework with many builtin image crawlers provided.
Stars: ✭ 629 (+424.17%)
Mutual labels:  crawler, scrapy
Scrapy Redis
Redis-based components for Scrapy.
Stars: ✭ 4,998 (+4065%)
Mutual labels:  crawler, scrapy
Scrapy Azuresearch Crawler Samples
Scrapy as a Web Crawler for Azure Search Samples
Stars: ✭ 20 (-83.33%)
Mutual labels:  crawler, scrapy
Vault
swiss army knife for hackers
Stars: ✭ 346 (+188.33%)
Mutual labels:  crawler, scrapy
Scrapple
A framework for creating semi-automatic web content extractors
Stars: ✭ 464 (+286.67%)
Mutual labels:  crawler, scrapy
Scrapy Examples
Some scrapy and web.py exmaples
Stars: ✭ 71 (-40.83%)
Mutual labels:  crawler, scrapy
Crawler
爬虫, http代理, 模拟登陆!
Stars: ✭ 106 (-11.67%)
Mutual labels:  crawler, scrapy

QQ音乐爬虫(with scrapy)/QQ Music Spider

UPDATE 2019.12.23

已实现对QQ音乐文件的下载,出于版权考虑,不对此部分代码进行公开。此项目仅作为学习交流使用,支持正版,人人有责

jaychou

项目介绍

  • 在写一个项目的时候需要用到一些音乐的信息,但是在网上找了许久也没找到满意的音乐语料,于是便用scrapy写了一个QQ音乐的爬虫
  • 由于本人只需要用到中文歌曲,所以仅使用该爬虫爬取了QQ音乐中排名前6400名的内地和港台歌手的49万+的歌曲信息,该资源也分享到了百度云(该资源仅用于学习交流,请勿用于商业用途,如有侵权,请联系删除)
  • QQ音乐的歌曲信息是使用js动态填充的,虽然QQ音乐的歌手和歌曲信息是使用GET进行明文请求,但是开发人员却在url请求参数上添加了一些冗余信息,对参数进行了一些加密,因此大部分精力还是花在了解析url上

运行环境

scrapy==1.5.1

使用方法

进入项目根目录,运行如下命令即可:scrapy crawl qqmusic

歌曲格式

爬取到的歌曲信息保存在根目录下的music文件中,每一行表示一条歌曲,存储格式为json

歌曲的字段说明:

  • singer_name:歌手名称,数组形式,因为一首歌可能由多名歌手合唱
  • song_name:歌曲名称
  • subtitle:歌曲的子标题
  • album_name:专辑名称
  • singer_id:歌手id,数组形式
  • singer_mid:歌手的mid,数组形式
  • song_time_public:歌曲发行时间
  • song_type:歌曲类型
  • language:歌曲语种
  • song_id:歌曲id
  • song_mid:歌曲mid
  • song_url:歌曲播放的url
  • lyric:歌词
  • hot_comments:歌曲的精彩评论(此处只爬取了歌曲的精彩评论,部分比较冷门的歌曲有最新评论,但是没有精彩评论),数组形式。若无精彩评论,置为"null"
    • comment_name:评论者的昵称
    • comment_text:评论内容

爬取说好不哭(with 五月天阿信)样例:

{
	'singer_name': ['周杰伦'],
	'song_name': '说好不哭(with 五月天阿信)',
	'subtitle': '',
	'album_name': '说好不哭(with 五月天阿信)',
	'singer_id': [4558],
	'singer_mid': ['0025NhlN2yWrP4'],
	'song_time_public': '2019-09-16',
	'song_type': 0,
	'language': 0,
	'song_id': 237773700,
	'song_mid': '001qvvgF38HVc4',
	'song_url': 'https://y.qq.com/n/yqq/song/001qvvgF38HVc4.html',
	'hot_comments': [{
		'comment_name': 'Cohen',
		'comment_text': '《说好不哭》是听众很期待的一个作品,前奏钢琴曲的渐入和后续的弦乐给整首歌奠定了温暖的基调。不知道大家有没有好好去看了这首歌的背景介绍“这是一首关于「约定」和「成全」的情歌,整首歌以钢琴为主要故事线,弦乐编织出抒情场景,营造出一种爱情电影的氛围”。依然的周式情歌,杰伦最总拿捏住每一首歌的感情基调,总能用最精妙的词曲和编曲打动他的听众。\\n\\n这首歌当然在合乎听众期待的同时,也给予了我们些许特别,第二段阿信的加入相信会令不少听众感到惊喜。对于我来说,我最喜欢整首歌的钢琴曲,温暖纯净感动,或许初遍听并非能完全理解杰伦想要告诉我们怎样的一个爱情故事,但是我们也能从简单的歌词和干净的旋律里感受到情感的部分。'
	}, {
		'comment_name': '野渡无人',
		'comment_text': '“我坚持我的音乐,我喜欢我的音乐,谁叫我是周杰伦。”或许喜欢他,正是因为他对音乐独有的专注认真,才令人对这个音乐才子着迷。\\n我相信很多人的青春里都有他,从曾经除了才华一无所有,无人知晓的少年,到如今的现代流行天王,周杰伦用一首首歌陪伴了我们整个青春,说生如逆旅,多少迷茫和气馁,却总能在他的歌声里找回自己。今岁不复去岁,人生这条人行道上,兜兜转转,还是一个周杰伦。\\n而这首《说好不哭》更像是一个约定,“你会微笑放手 说好不哭让我走” ,而我们不远万里赴约,这就是周杰伦,即青春。\\n'
	}, {
		'comment_name': '是硬糖啊',
		'comment_text': '对于很多80后90后来说,青春或许就这样悄然慢慢过去了,我依稀还记得那个夏天里七里香的香味,还有那个唱着《简单爱》,表情酷酷的男孩。\\n静静听了一遍,还是那个熟悉的风格,那个熟悉的Jay。也许杰伦的嗓音已经有了变化,但是在歌里他依旧延续着那份感动。\\n喜欢Jay的歌,忘不了有多少个夜晚的歌单循环,忘不了有多少次的辗转反侧。他的歌曲,经常会在某个时间点引发你的共鸣。\\n说好不哭,可是有多少人还是会泪流满面,可能是因为40岁的杰伦终于发了新歌,也可能是因为有些过往,有些感动,真的再也回不去了……'
	}, {
		'comment_name': '墨染栀',
		'comment_text': 'Jay式情歌重磅回归,期待了已久的歌。方文山再次作词走心之作,前奏已沉醉。最惊喜的是阿信献声。一个弹琴一个弹吉他,简直是神仙合作。1分40秒左右旋律是五月天的“突然好想你,你会在哪里?”。1分47秒的旋律是《说好的幸福呢》,然后进入阿信的part。杰伦歌里总能藏着这些细腻。我们的青春圆满了。缓缓的钢琴声诉说着凄美的爱情。有一种爱叫默默奉献,无需言语。有一种爱叫放手,你过得幸福就好。距上一次发新歌时隔一年了,40岁的周董是多少人的青春年华,熟悉的旋律是不是依旧耳边回荡。从第一张个人专辑《Jay》到如今,我们热情不减,周董惊喜不断。周杰伦——一个代表时代歌手拥有的魅力。说好不哭,你哭了吗?'
	}, {
		'comment_name': '森岛帆高',
		'comment_text': '初中时的哥哥买的一盒盒堆积成山周杰伦封面的磁带。\\n磁带放入收音机,磁带转动起,每一个停顿瞬间,每一首风格独特,每一句声声入耳。从懵懂到成熟,都是喜欢周杰伦的年轮。\\n在这磁带转动的年轮里,歌曲播放的列表里,生活情绪的喜悲里,一尘不变的还是周杰伦的歌。\\n他的歌包揽了我的一整个年少,度过了我的大半个学生时代,陪伴了我的无数个孤独夜晚。\\n百听不厌可能是对他的歌最完美的诠释吧。\\n周杰伦是我的信念,是我的力量。\\n如今哥哥也已经参加工作,我的学生时代也转瞬即逝。\\n对周杰伦的喜欢怕是听着他音乐的旋律融到了心里,伴随而去了吧。'
	}, {
		'comment_name': '玫瑰少年',
		'comment_text': '今年,杰伦40岁了,但我脑海中却还是那个充满个性,说着“可不可以多唱歌少讲话”的男孩子....《说好不哭》其实可能也是杰伦的心里话,可能以后出歌不会像以前那样快了,也在担心自己歌曲是否还能符合粉丝的要求,但说好不哭哦。\\n我相信对于很多粉丝来说,杰伦已经给予了一个完整的音乐海洋,无论伤心快乐,他好像总有为你匹配的歌曲,时时刻刻呵护着自己的情感,即使在各类歌曲百花齐放的今天,每一个夜晚依旧喜欢在他的歌声中入睡。\\n不会哭的,无论过去还是未来,我们还是愿意让你的歌声陪伴着我们,陪伴着整个青春,陪伴一辈子。'
	}, {
		'comment_name': '蜗牛..',
		'comment_text': '我想,你的青春里一定有一首歌是属于Jay的吧。躺在心里,偶而翻出,正好遇上那个情绪,便产生某些新的情感和新的认知。一场青春,一首周杰伦,沮丧时听听,不论是温柔的还是奋进的,总能唱到元气满满。好的音乐,是会说话的。\n仿佛每次在挣扎,迷茫和无助的时候,都能在他的音乐世界里慢慢治愈,而音乐和周杰伦本就是一次相互成全的相遇。\n青春难以留住,夏天已然散场。人生的道路也许各不相同,但只要在他需要我们的时候为他加油喝彩,就足够了,那才叫青春。\n不管什么时候,什么地点,我希望所有歌迷回过头来看到的还是同一个周杰伦。'
	}, {
		'comment_name': '此用户已被封',
		'comment_text': '周杰伦三个字是一代青春,还记得08年晚会上听的那首《青花瓷》顿时茅塞顿开,世间静会有如此好听的歌曲。之后迷上他的所有歌曲,自己买磁带上学的时候在宿舍晚上听,陪我渡过了5年学习生涯。这次我们的周青春出新歌,前些天一直在等待,熬夜等待但我觉得这些所有的等待都是值得的。'
	}, {
		'comment_name': '黄子韬TAO',
		'comment_text': '人气top周杰伦❗💎💖✨🌈\\n实力歌手周杰伦❗💎💖✨🌈\\n音乐鬼才周杰伦❗💎💖✨🌈\\n亚洲天王周杰伦❗💎💖✨🌈\\n家庭美满周杰伦❗💎💖✨🌈\\n魔术大师周杰伦❗️💎💖✨🌈\\n华语天王周杰伦❗️💎💖✨🌈\\n无与伦比周杰伦❗️💎💖✨🌈\\n奶茶仙子周杰伦❗️💎💖✨🌈\\n守护全世界最好的周杰伦💖💖💖'
	}, {
		'comment_name': '指法芬芳张大仙z',
		'comment_text': '曾经傲娇的少年,\\n也已到了不惑之年,\\n从一个总是喜欢将脸庞隐藏在鸭舌帽下的腼腆男孩,\\n到如今撒娇卖萌幽默语句频出还时时撒狗粮的小公举,\\n新专辑如约而至,\\n能在这个时代遇到杰伦哥是人生最大幸运,\\n他的作品照亮你的路,陪伴你度过漫长的深夜,\\n你的支持和包容,也让他从默默无闻变成万众瞩目,\\n也许有一天 你忙于生活 他归于沉寂 渐渐不再会有交集\xa0,\\n希望在慢慢老去 还能回忆起青春时 曾为一个人疯狂追逐过,\\n他的名字就是\\n周!杰!伦!一生所爱 JAY\\n感谢你的音乐\\n让我有了一直学习吉他的动力,\\n感谢你的音乐\\n陪我度过的每一个夜晚,\\n感谢你的音乐\\n陪伴我在篮球场上的每一天,\\n青春有你,如此甚好,JAY !'
	}, {
		'comment_name': '指法芬芳张大仙z',
		'comment_text': '40岁的杰伦就坐在那里,\\n深情的目光望过去,\\n满眼都是自己当年22岁横空出世范特西少年身影......\\n作为华语乐坛最成功最具有影响力的歌手音乐人,\\n15座金曲奖、八届大中华区销量冠军、4届世界音乐奖WMA、全球25大创意人物、《Fast Company》全球百大创意人物,2010年歌曲下载量世界第三,历史上第一首好莱坞中文主题曲,亚洲天王,世界十大鬼才音乐人之一,\\n这就是周杰伦,是信仰,是天才,是一个时代,是传奇,是华人之光,是80后的回忆,90后的青春,他还见证着00后的成长;\\n感谢我伦,\\n你走过的轨迹是青春的记忆,\\n致敬,周杰伦!\\n永远的小公举,永远的热爱!'
	}, {
		'comment_name': '指法芬芳张大仙z',
		'comment_text': '难以忘记初次遇见你,是在《红尘客栈》的《大笨钟》下,你笑得《甜甜的》像是天边的一道《彩虹》色的《麦芽糖》;他们都说爱情来的太快像是《龙卷风》,你和我《一点点》靠近,相识,相恋;我经常会《安静》的看着你《傻笑》,表白《说好不哭》陪你到永远;在每个《晴天》里,我都会在学校的篮球场上《等你下课》;我的女孩,你就像是我《不能说的秘密》,我想给你《告白气球》般的浪漫,我想和你许下《蒲公英的约定》,然后牵起你的手,用吉他弹起那《手写的从前》,就这样一直牵着你去看《最长的电影》,在每个夜晚里去看最美的《星晴》,直到永远;我的女孩,你就像是海里的《美人鱼》公主,我愿做你的王子,一直爱你❤一直守护在你身边。😘'
	}, {
		'comment_name': '黄子韬TAO',
		'comment_text': '手牵手,一步两步三步四步望着天\\n看星星,一颗两颗三颗四颗连成线\\n周杰伦“说”三部曲将会在2019年9月16日正式完结\\n千万别错过,这一错就是一辈子!'
	}, {
		'comment_name': '\u2062',
		'comment_text': '周杰伦\\n我QQ音乐里唯一的主角\\n你说要听妈妈的话喝爷爷泡的茶\\n你说最美的是与你躲过雨的屋檐下\\n我提一笔想用几行字形容你是我的谁\\n礼物用香榭的落叶就不会觉得有点难追\\n时间是解药也是我现在服下的这一剂毒药\\n我的十八年青春因为有你的出现而引以为傲\\n只要你还在为我们唱还在带着笑面对逆境环绕\\n风就不会把距离吹得好远我的青春也不会老\\n有人说你江郎才尽才华不复当年模样\\n那是他们嫉妒你绝世的巅峰和辉煌\\n今晚说好不哭\\n谢谢你在一直陪伴着我的青春\\n❤️❤️❤️'
	}, {
		'comment_name': '指法芬芳张大仙z',
		'comment_text': '青春不散!东方之殿开轩窗,绘梦之卷迷迭香,献世青花瓷世无双,情书却渐黄,手书兰亭序,孤饮女儿红,乱舞春秋夜未央,园游会下灿烂七里香,遥思娘子在西厢,抚断了的弦,奏夜的第七章,同一种调调徒感伤。枫叶落光,花海安静夜曲入乡,忍者星晴夜望,摩羯座非寻常,梯田闻稻香,甜甜的心雨洒晴天,将军屋顶发呆,懦夫将被淘汰,我不配周大侠龙战骑士那神态,没借口不退后,以父之名远走,拜别霍元甲,身披黄金甲,持双截棍耍帅,一路向北过千山万水漂移而来,赴千里之外菊花台, 龙卷风兼蓝色风暴雨,四面楚歌响起,止战之殇的记忆、逆鳞的轨迹,乘坐时光机,世界末日又回到过去,简单爱在爱的飞行日记里一直搁浅下去。'
	}],
	'lyric': '说好不哭(with 五月天阿信) - 周杰伦 (Jay Chou)\\n词:方文山\\n曲:周杰伦\\n周杰伦:\\n没有了联络 后来的生活\\n我都是听别人说\\n说你怎么了 说你怎么过\\n放不下的人是我\\n人多的时候 就待在角落\\n就怕别人问起我\\n你们怎么了 你低着头\\n护着我连抱怨都没有\\n电话开始躲 从不对我说\\n不习惯一个人生活\\n离开我以后 要我好好过\\n怕打扰想自由的我\\n都这个时候 你还在意着\\n别人是怎么怎么看我的\\n拼命解释着 不是我的错 是你要走\\n眼看着你难过 挽留的话却没有说\\n你会微笑放手 说好不哭让我走\\n阿信:\\n电话开始躲 从不对我说\\n不习惯一个人生活\\n离开我以后 要我好好过\\n怕打扰想自由的我\\n都这个时候 你还在意着\\n别人是怎么怎么看我的\\n拼命解释着 不是我的错 是你要走\\n合:\\n眼看着你难过 挽留的话却没有说\\n你会微笑放手 说好不哭让我走\\n周杰伦:\\n你什么都没有 却还为我的梦加油\\n阿信:\\n心疼过了多久\\n周杰伦:\\n过了多久\\n合:\\n还在找理由等我'
}

爬虫的大致逻辑

  • 先爬取指定数量的歌手
  • 根据歌手的id,获取每一位歌手的歌曲列表(歌曲列表中包含歌曲的一些信息,但不包括歌词和评论信息)
  • 根据歌曲id,获取歌曲的歌词信息
  • 根据歌曲id,获取歌曲的评论信息
  • 将歌曲写入文件

语料分享

该资源仅用于学习交流,请勿用于商业用途,如有侵权,请联系删除。

语料名称 语料地址 语料描述
49万+的歌曲信息 百度网盘【提取码:uokb】 包含QQ音乐中排名前6400名的内地和港台歌手的49万+的歌曲信息,包含歌曲信息、歌词、精彩评论等

解析QQ音乐的url

QQ音乐的歌手和歌曲信息,都是使用js进行动态填充的,所以不可能通过爬取html网页,然后解析网页内容来获取歌曲信息。既然是通过js进行动态填充,那就需要对请求的url的格式进行解析

歌手列表url解析

打开QQ音乐的 歌手页面 ,用开发者工具查看,找到请求歌手列表的url如下:

https://u.y.qq.com/cgi-bin/musicu.fcg?-=getUCGI9574303950614538&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A0%2C%22cur_page%22%3A1%7D%7D%7D

可以看到url中携带了很多参数,包括:g_tk、loginUin、hostUin、format、inCharset、outCharset、notice、platform、needNewCode、data

将该url放到postman中,尝试一个接一个地取消参数,找到有用的参数。最终可以知道,其实只有data这个参数对请求有实际的作用,把其他参数去掉,得到简化后的url如下:

https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A0%2C%22cur_page%22%3A1%7D%7D%7D

结合歌手页面,仔细分析一下上述简化后的url,会发现data参数中隐含地携带了很多实际的请求参数:

  • area:歌手的地域(内地、港台、欧美等)。-100:全部、200:内地、2:港台、5:欧美、4:日本、3:韩国、6:其他
  • genre:歌手风格(流行、嘻哈等)。-100:全部、1:流行、6:嘻哈、2:摇滚、4:电子、3:民谣、8:R&B、10:民歌、9:轻音乐、5:爵士、14:古典、25:乡村、20:蓝调
  • cur_page:当前歌手列表的页码
  • index:cur_page*page_size(index表示当前页的起始index,page_size表示每一页歌手的数量)

使用控制变量法,固定area和genre变量,比较下列请求第一、二、三页歌手的url,可以发现其中index和cur_page中存在一些潜在规律

在下列三个url中(*是人为添加的,方便描述),index后面跟着的用**标记的数字就是变量index,cur_page后面用 **标记的数字就是变量cur_page。在歌手页面,可以看到每一页有80个歌手。很显然,当要请求第n页歌手的时候,cur_page=n,index=80(n-1)。

https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A**0**%2C%22cur_page%22%3A**1**%7D%7D%7D

https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A**80**%2C%22cur_page%22%3A**2**%7D%7D%7D

https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A**160**%2C%22cur_page%22%3A**3**%7D%7D%7D

通过以上分析,可以得到请求歌手列表的url格式如下:

singer_list_url = "https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A{area}%2C%22sex%22%3A-100%2C%22genre%22%3A{genre}%2C%22index%22%3A-100%2C%22sin%22%3A{index}%2C%22cur_page%22%3A{cur_page}%7D%7D%7D"

歌曲列表url解析

同理找到请求歌曲列表的url

https://u.y.qq.com/cgi-bin/musicu.fcg?-=getSingerSong8235365887193979&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerSongList%22%3A%7B%22method%22%3A%22GetSingerSongList%22%2C%22param%22%3A%7B%22order%22%3A1%2C%22singerMid%22%3A%22004Be55m1SJaLk%22%2C%22begin%22%3A0%2C%22num%22%3A10%7D%2C%22module%22%3A%22musichall.song_list_server%22%7D%7D

过滤掉无用的参数,得到简化后的url:

https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerSongList%22%3A%7B%22method%22%3A%22GetSingerSongList%22%2C%22param%22%3A%7B%22order%22%3A1%2C%22singerMid%22%3A%22004Be55m1SJaLk%22%2C%22begin%22%3A0%2C%22num%22%3A10%7D%2C%22module%22%3A%22musichall.song_list_server%22%7D%7D

data中隐藏的参数:

  • singerMid:歌手的mid
  • num:相当于page_size,表示每一页歌曲的数量
  • begin:page*page_size(begin表示当前页的起始index)

通过以上分析,可以得到请求歌曲列表的url格式如下:

song_list_url = "https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerSongList%22%3A%7B%22method%22%3A%22GetSingerSongList%22%2C%22param%22%3A%7B%22order%22%3A1%2C%22singerMid%22%3A%22{singer_mid}%22%2C%22begin%22%3A{begin}%2C%22num%22%3A{num}%7D%2C%22module%22%3A%22musichall.song_list_server%22%7D%7D"

请求歌词url解析

通过请求歌曲列表的url发现,并没有返回歌曲的歌词信息,因此肯定是通过额外的url请求获得歌词,找到请求歌词的url如下:

https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg?nobase64=1&musicid=105648715&-=jsonp1&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0

将以上url放到postman中发送请求,却得不到正确的回复,经过一番研究,发现该url需要加上referer这个header才可以正常运行

referer:https://y.qq.com/n/yqq/song/004RDW5Q2ol2jj.html

请求歌词的url经过简化参数后得到:

https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg?musicid=105648715&format=json

容易看出

  • musicid:song_id
  • referer中的"004RDW5Q2ol2jj"表示song_mid

最终得到请求歌词的url如下,lyric_url需要带上referer这个header:

lyric_url = "https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg?nobase64=1&musicid={song_id}&format=json"

referer = "https://y.qq.com/n/yqq/song/{song_mid}.html"

歌曲评论url解析

找到歌曲评论的url如下:

https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg?g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=GB2312&notice=0&platform=yqq.json&needNewCode=0&cid=205360772&reqtype=2&biztype=1&topid=105648715&cmd=8&needmusiccrit=0&pagenum=0&pagesize=25&lasthotcommentid=&domain=qq.com&ct=24&cv=10101010

经过参数简化后,得到如下url:

https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg?biztype=1&topid=105648715&cmd=8&pagenum=0&pagesize=25

参数说明:

  • topid:歌曲的song_id
  • pagenum:"最新评论"的页数
  • pagesize:每页"最新评论"的评论数量

注意:此处的pagenum和pagesize影响的是"最新评论"的返回结果,而不影响"精彩评论",该url中没有参数可以控制"精彩评论"的返回结果

请求歌曲评论的url格式如下:

comment_url = 'https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg?biztype=1&topid={song_id}&cmd=8&pagenum={pagenum}&pagesize={pagesize}'

歌曲url

歌曲的url格式如下:

https://y.qq.com/n/yqq/song/{song_mid}.html

歌词解析

以周杰伦的说好不哭(with 五月天阿信)为例

通过lyric_url请求获得的歌词格式如下,格式看起来还是比较杂乱的,包含各种字符

[ti:说好不哭(With 五月天阿信)]
[ar:周杰伦]
[al:说好不哭(With 五月天阿信)]

[by:]
[offset:0]
[00:00.00]说好不哭(with 五月天阿信) - 周杰伦 (Jay Chou)

[00:14.94]词:方文山
[00:19.09]曲:周杰伦
[00:23.24]周杰伦:

[00:26.51]没有了联络 后来的生活
[00:29.76]我都是听别人说
[00:32.85]说你怎么了 说你怎么过

[00:36.02]放不下的人是我
[00:39.20]人多的时候 就待在角落
[00:42.34]就怕别人问起我

[00:45.37]你们怎么了 你低着头
[00:48.30]护着我连抱怨都没有
[00:51.82]电话开始躲 从不对我说

[00:54.98]不习惯一个人生活
[00:58.11]离开我以后 要我好好过
[01:01.32]怕打扰想自由的我

[01:04.39]都这个时候 你还在意着
[01:07.56]别人是怎么怎么看我的
[01:10.77]拼命解释着 不是我的错 是你要走

[01:15.55]眼看着你难过 挽留的话却没有说
[01:28.14]你会微笑放手 说好不哭让我走
[01:52.13]阿信:

[01:54.95]电话开始躲 从不对我说
[01:58.17]不习惯一个人生活
[02:01.26]离开我以后 要我好好过

[02:04.41]怕打扰想自由的我
[02:07.62]都这个时候 你还在意着
[02:10.62]别人是怎么怎么看我的

[02:13.90]拼命解释着 不是我的错 是你要走
[02:18.51]合:
[02:18.71]眼看着你难过 挽留的话却没有说

[02:31.28]你会微笑放手 说好不哭让我走
[02:50.54]周杰伦:
[02:53.38]你什么都没有 却还为我的梦加油

[03:04.99]阿信:
[03:05.92]心疼过了多久
[03:09.83]周杰伦:
[03:10.02]过了多久

[03:12.58]合:
[03:12.77]还在找理由等我

通过正则表达式得到比较工整的歌词(每句歌词之间用\\n间隔开):

说好不哭(with 五月天阿信) - 周杰伦 (Jay Chou)\\n
词:方文山\\n
曲:周杰伦\\n
周杰伦:\\n
没有了联络 后来的生活\\n
我都是听别人说\\n
说你怎么了 说你怎么过\\n
放不下的人是我\\n
人多的时候 就待在角落\\n
就怕别人问起我\\n
你们怎么了 你低着头\\n
护着我连抱怨都没有\\n
电话开始躲 从不对我说\\n
不习惯一个人生活\\n
离开我以后 要我好好过\\n
怕打扰想自由的我\\n
都这个时候 你还在意着\\n
别人是怎么怎么看我的\\n
拼命解释着 不是我的错 是你要走\\n
眼看着你难过 挽留的话却没有说\\n
你会微笑放手 说好不哭让我走\\n
阿信:\\n
电话开始躲 从不对我说\\n
不习惯一个人生活\\n
离开我以后 要我好好过\\n
怕打扰想自由的我\\n
都这个时候 你还在意着\\n
别人是怎么怎么看我的\\n
拼命解释着 不是我的错 是你要走\\n
合:\\n
眼看着你难过 挽留的话却没有说\\n
你会微笑放手 说好不哭让我走\\n
周杰伦:\\n
你什么都没有 却还为我的梦加油\\n
阿信:\\n
心疼过了多久\\n
周杰伦:\\n
过了多久\\n
合:\\n
还在找理由等我

settings.py的参数说明

  • DOWNLOAD_DELAY:每个request请求的间隔时间
  • ROBOTSTXT_OBEY:是否遵守网站的爬虫协议
  • SINGER_PAGE_NUM:爬取的歌手页数
  • SINGER_PAGE_SIZE:每页歌手的数量
  • SONG_PAGE_NUM:每个歌手的歌曲爬取的页数
  • SONG_PAGE_SIZE:每个歌手每页歌曲的数量

避免爬虫被ban

  • 使用user agent池,轮流选择其中一个作为user agent
  • 设置下载延迟DOWNLOAD_DELAY,设为1或者更大。(一开始怕QQ音乐官方会有一些反爬虫的检测,于是把DOWNLOAD_DELAY设为1,也就是每隔一秒钟才发送一次请求,发觉爬取速度过于慢,又改成了0.1。最终索性设为0,发现原来QQ音乐对于歌词信息的url并没有反爬虫措施)
  • 使用IP池,动态变更IP地址

user agent池如下:

"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"

Future Work

  • 解析QQ音乐的歌曲文件的请求方式
  • 韩文和英文歌词中包含一些特殊的符号,部分特殊字符还没能较好地进行转义
  • 完善setting,使用户能更灵活地爬取不同地域、风格的歌曲

未解决问题

程序可以正常运行,但是当爬取结束时(日志信息写着'finish_reason':'finished',表明爬虫爬取任务完成),报了一个错,虽然不影响结果,但报错原因暂时不明

2019-12-21 15:08:53 [scrapy.core.engine] INFO: Closing spider (finished)
2019-12-21 15:08:53 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/exception_count': 8,
 'downloader/exception_type_count/twisted.internet.error.TimeoutError': 8,
 'downloader/request_bytes': 682269284,
 'downloader/request_count': 1067470,
 'downloader/request_method_count/GET': 1067470,
 'downloader/response_bytes': 1563129445,
 'downloader/response_count': 1067462,
 'downloader/response_status_count/200': 1067460,
 'downloader/response_status_count/404': 2,
 'dupefilter/filtered': 30476,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2019, 12, 21, 7, 8, 53, 816618),
 'item_scraped_count': 489860,
 'log_count/DEBUG': 1557332,
 'log_count/ERROR': 1,
 'log_count/INFO': 229,
 'request_depth_max': 3,
 'response_received_count': 1067462,
 'retry/count': 8,
 'retry/reason_count/twisted.internet.error.TimeoutError': 8,
 'scheduler/dequeued': 1067468,
 'scheduler/dequeued/memory': 1067468,
 'scheduler/enqueued': 1067468,
 'scheduler/enqueued/memory': 1067468,
 'start_time': datetime.datetime(2019, 12, 20, 14, 59, 43, 749919)}
2019-12-21 15:08:53 [scrapy.core.engine] INFO: Spider closed (finished)
2019-12-21 15:08:53 [scrapy.utils.signal] ERROR: Error caught on signal handler: <bound method MemoryUsage.engine_stopped of <scrapy.extensions.memus
age.MemoryUsage object at 0x000001EFCF7E8630>>
Traceback (most recent call last):
  File "c:\users\administrator\.conda\envs\ppy36\lib\site-packages\twisted\internet\defer.py", line 151, in maybeDeferred
    result = f(*args, **kw)
  File "c:\users\administrator\.conda\envs\ppy36\lib\site-packages\pydispatch\robustapply.py", line 54, in robustApply
    return receiver(*arguments, **named)
  File "c:\users\administrator\.conda\envs\ppy36\lib\site-packages\scrapy\extensions\memusage.py", line 70, in engine_stopped
    for tsk in self.tasks:
AttributeError: 'MemoryUsage' object has no attribute 'tasks'

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].