爬取网易云音乐评论2

Intro

前一阵子写了个爬取网易云音乐评论的python程序
但是只是完成了一个开端,最近抽空稍微完善了一下

先看一下整体流程

  1. 获取要爬取的歌手的ID
  2. 通过ID获取这个歌手的所有专辑ID
  3. 通过专辑获取歌手的所有歌曲
  4. 歌曲间一个一个的通过爬虫进行爬取

Problem

这里面存在几个问题

  1. 怎么判断一个歌曲或者一张专辑已经爬过了
  2. 怎么保证爬取的效率
  3. 怎样防止网易的反爬虫机制

Solution1

目前只解决了第一个问题,我的方法是先生成一个Task表,将任务以及任务的进度存储在Task表中,每次重新运行的时候先从Task表中读取进度,然后再进行爬取操作。

TaskSchedule.json

[{
    "id": "35520072",
    "isCrawler": 1,
    "musicId": "2116",
    "name": "\u653e & \u62ab\u98ce",
    "songs": [{
        "album": "35520072",
        "isCrawler": 1,
        "id": "478731242",
        "name": "\u653e",
        "offset": "-1"
    }, {
        "album": "35520072",
        "isCrawler": 0,
        "id": "478736172",
        "name": "\u62ab\u98ce",
        "offset": "530"
    }]
}, {...}]

如上形成json格式的一个文件,将专辑ID和是否爬取存入,offset代表这首歌爬取到了第几个评论,每次爬取完通知爬取者取更新这张表(通过调用trigger方法)

def trigger(self,musicId,offset):
    isOk = False
    albumList = self.load()
    for album in albumList:
        if isOk:
            break

        if album["isCrawler"] == 1:
            continue
        for song in album["songs"]:
            if song["id"] == musicId:
                if offset == -1:
                    song["isCrawler"] = 1
                    for song in album["songs"]:
                        isCrawler = 1
                        if song["isCrawler"] == 0:
                            isCrawler = 0
                            break
                    album["isCrawler"] = isCrawler
                else:
                    song["offset"] = offset
                isOk = True
                logger.critical("%s has fininsh with %s"%(str(musicId),str(offset)))
                break

    self.store(albumList)

Solution2

第二个问题可以用多线程去解决,虽然Python本质上没有多线程,但是在IO密集型操作中,类似爬虫发送http请求的操作中存在大量IO操作,因此多线程还是可以几何倍增加爬取速度的。

方法就是将要爬取得内容放进队列中,然后多线程利用线程池进行出队操作选择要爬取的对象。这一部分待完工。

Solution3

第三个问题存在于爬取的测试过程中,在爬取中不一会就出现503拒绝访问的错误。这是网易云音乐对API的保护,我们只能利用爬虫代理进行深一步操作,待完工。

最后附一个爬取时候的截图
爬取网易云音乐评论2_第1张图片

Github: https://github.com/WJerry0227/MusicComment163

持续更新中。。。

你可能感兴趣的:(爬虫)