lyyyuna 的小花园

动静中之动, by

RSS

分布式 B 站用户信息爬虫

发表于 2017-04

前言

上周末写了一个 B 站用户信息爬虫,怎么爬网页实在是没什么好讲的,所以这篇描述一下简单的分布式爬虫。

知乎和 B 站用户爬虫极其类似。它们都有两种爬取策略:

自增数字的方式程序更容易实现。

换代理的痛点

剩下的问题就是反爬虫,简单的换 header 头部就不说了,因为 B 站和知乎都是根据 IP 来反爬,那么我能想到的就只有:

从实现方式看,代理也能看作是一个分布式爬虫。根据 HTTP 返回的状态码,可以判断:

基于上述判断,可以实现一些复杂的代理切换策略:

不幸的是,免费好用的代理非常难找,使用 scrapy 配上我写的几百行的代理中间件,也很难维持一个正常的下载速率。 用 Python 来爬虫几乎是网上教程的标配了 -_-,导致即使找到一个可用代理,其 IP 也早被列入服务器的黑名单。

分布式爬虫

基于 HTTP 服务器实现分布式

基于 HTTP 服务器的分布式爬虫

优点是:

缺点是:

这个链接https://github.com/lyyyuna/zhihu_user_papapa里是用这种思路实现的 B 站用户爬虫。

基于消息队列实现分布式

基于消息队列实现分布式爬虫

采用消息队列后,Producer 主控侧不再是被动地发布任务,而是主动推送任务。上一小节有的优点消息队列同样拥有,同时

这种结构的分布式爬虫,同样需要显示地维护一来一回蓝色红色的数据流,还是稍显复杂。

基于 Celery 任务队列实现分布式

基于 Celery 实现分布式爬虫

初看上去,这个结构和上一节没有区别,但是,上图的红色数据流是不需要显示维护的!

举一个简单例子。假设在机器 A,有如下的 worker

from celery import Celery

app = Celery('tasks', broker='pyamqp://guest@localhost//')

@app.task
def add(x, y):
    return x + y

那么在另一台机器 B,只要运行

from tasks import add
result = add.delay(4, 4)

就能得到结果。同时

基于这个思想,我完成了这个分布式爬虫https://github.com/lyyyuna/bilibili_papapa。只需要 Celery 的 broker 具有公网 IP,然后把程序扔给朋友让他们帮我跑就行。唯一的不便是 Celery worker 在个人电脑上部署不便,而基于 HTTP 的分布式爬虫,我只要 C# 写个 HTTP 客户端生成 exe 就可以了。