Scrapy爬取网易云音乐和评论(一、思路分析)

目录:

1、Scrapy爬取网易云音乐和评论(一、思路分析)
2、Scrapy爬取网易云音乐和评论(二、Scrapy框架每个模块的作用)
3、Scrapy爬取网易云音乐和评论(三、爬取歌手)
4、Scrapy爬取网易云音乐和评论(四、关于API)
5、Scrapy爬取网易云音乐和评论(五、评论)

前提:

  1. scrapy这个框架很多人用过,网上教程也很多,但大多就是爬爬小说这种比较简单且有规律的。尤其大多网站它是可以通过点击下一页的方式爬取下一页,我看到的教程也都是这样的。而网易云的按钮光页面不采取类似selenium这样的模拟浏览器的模块是获取不到的,加上有API,所以换种方式。

  2. 网易云音乐也有很多人写过,也有API,不过大多是爬取了热门歌曲,或是从歌单下手。但是考虑到歌单会有大量重复的,我则从歌手下手——
    当然,从歌手页的话,如果有多个歌手合唱,那每个歌手页也都会有这首歌,但他们的链接是一样的,也是会有重复的,但是相对来说就比较少。
    在GitHub上也有很多优秀的例子,例如,我写的时候关于开头参考了这篇:https://github.com/runningRobin/music163/blob/master/music163/spiders/spider.py,但是它没有文档,我这里写一个整站的。

个人认为scrapy的一些不足

1、在写的过程中,发现scrapy这个框架其实不是那么完美,它对上手的要求有点高,而且又有些束缚,尤其是对数据库的操作,不是那么的完美。

2、再比如我要设置一些已经存在的url跳过(在没有索引的情况下),而scrapy它本身就是一个各个功能分开写的,pinelines这个文件是处理数据库的,但我要处理存在的url跳过,pinelines就不方便了,还有些可能就要写到程序,这就相悖了。所以我后来还是没有用框架又写了一遍。这一块就拿出来当教程吧。

开发环境:WIN7+Anaconda+py2.7+scrapy
数据库:MongoDB
文章的顺序
1、先分析思路;
2、再分析scrapy框架每个模块的作用;
3、最后写代码和分析API,以及评论
只有5篇,不会把完整的代码贴出来,因为思路很重要,有了思路,懂得基本操作和顺序,自己折腾就折腾出来了。

一、我们先分析歌手,有两种方法:

方法一:遍历

优点:有个别歌手有主页,但是没有申请音乐人,所以不存在歌单列表页,用第二种方法也获取不到。
缺点:不好测试它到底有多少,大概十一二万的样子,大多id是相隔不远的。有些id之间相隔了几位数,本来挺稳定的,想着往4位数遍历就行,却发现还有7位数的,这样遍历的跨度有些大,(id从1872开始),要做些处理,还有判断这个页面存在与否。

方法二:从歌手分类爬取所有歌手的id

歌手分类页http://music.163.com/#/discover/artist
这里要说一下,网易云的所有网址,要去掉中间那个#号才是真正的url,带#的查看源代码是获取不到真正的信息的。
所以其实是:http://music.163.com/discover/artist

优点:方便,不需要考虑遍历的数量,不需要对页面是否存在做处理
缺点:可能会漏掉一些有主页但未注册的歌手。

我们主要以方法二入手,分析如下:

我们看这个页面左侧栏:

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图一

2、因为当时我写的时候,参考到前面提到的那篇GitHub上的代码,
这个group_ids里的就是左侧每个项对应所有的页面了(不包括最上方的推荐歌手和入驻歌手,因为包含在其他里面了)

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图二 左栏里的id

3、我们按F12或右键检查,如图,每个对应的url是:http://music.163.com/discover/artist/cat?id=xxx
这里的id就是上面group_ids里的数字了。

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图三

4、然后我们再点进去,如图四,url的id就是上面这个group_ids里的元素了,而后面的initial是首字母的意思,你看下面我们选中的是A,然后它是65,是不是想到ASCII码?在ASCII码中A就是从65开始的,Z是90,后面以此类推,最后有个其他,代替的是0:

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图四

我们将这两个分别存储为一个列表或元组:

#  左侧栏所有:男女、国家分类id
group_ids = (1001, 1002, 1003, 2001, 2002, 2003, 6001, 6002, 6003, 7001, 7002, 7003, 4001, 4002, 4003)
# 歌手姓名首字母id
initials = [i for i in range(65,91)] + [0]

二、歌手页

1、点进来之后我们来到歌手页,http://music.163.com/#/artist?id=6452,同样,查看源代码的时候去掉url里的#

2、我们获取的这个歌手页的url对应的是热门50首,在对应网页里我们会发现下面有好几个块:热门50首专辑MV歌手介绍

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图五

3、因为受框架的限制,以上四个信息的内容不在一个传递链里,
以下两种顺序的特点都是后者传入的参数都是由前者返回的,而这四个之间属于相同的id,他们并不需要由前者返回,不构成一个传递链:

1)、歌手 ——>专辑列表——>歌曲列表——>歌曲信息——>第5
2)、歌手 ——>热门50首的歌曲列表——>歌曲信息——>第4

4、如果如果你只需要热门歌曲你可以获取它所有链接,这个代码被我分为两块:
1)、第一块是包含热门50首的url,也只有url,在id名为‘song-list-pre-cache’的div标签里,div->ul->li->a->href
2)、而第二块textarea里是json,是这50首歌的比较完整的信息,只不过,这些信息通过lxml.etree或者BeautifulSoup用text的方式获取下来会是字符串,我们需要用json将它格式化。
如果你只需要歌曲的话,选择第一条就好了,直接跳到第四篇讲API的),用歌曲的API即可。

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图六 热门50首歌曲的所有链接或者json

5、我们要获取所有歌手的歌曲,就得从歌手的专辑下手,获取专辑里所有的歌手才行。我们在专辑页会发现,有些是有很多页的,我最开始用的是scrapy的xpath解析页面,后来搜的时候发现了API,所以接下来的东西,我们就不通过页面的方式了,API我是通过这个网站发现的:http://moonlib.com/606.html(最近发现网站挂了,请看我的第四篇讲API的,有其他类似API的文章链接)。

我们用到的是2到6(不包括5,没用到歌单),第7条接口是MV的,不过不幸没有发现像专辑一样的列表页信息,它只有单曲的MV的API。不过这里我们用不上。后面第四篇会专门分析API。

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图七

6、接下来就是每个专辑的所有歌曲还有专辑、歌手的一些信息,另外专辑下也有评论,且评论数的获取方式有些不同,因此评论有两种处理。

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图八 专辑信息、歌曲列表

7、最后从图八里的歌曲链接点进去的就是歌曲页了,如图九:

《Scrapy爬取网易云音乐和评论(一、思路分析)》 图九

好,思路就是这样,接下来我们分析Scrapy这个框架。

    原文作者:Python_1024
    原文地址: https://www.jianshu.com/p/c479ea1a4e0b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞