Scrapy_redis+scrapyd搭建分布式架构爬取知乎用户信息

相关背景:前几天写了个用scrapy爬取知乎用户信息的爬虫(http://blog.csdn.net/qq_40717846/article/details/78950519),今天结合这个爬虫,写一个利用scrapy-redis+scrapyd构建分布式爬取知乎用户信息的爬虫。

相关准备

win10操作系统,腾讯云服务器,redis,redis dedktop manager,Mongodb
1.在项目开始之前,请确保win10以及服务器都安装了redis以及mongodb,并且以win10为主机,win10的redis能够远程连接服务器的redis。
win 10安装Redis:https://github.com/rgl/redis/downloads
centos 安装Redis:直接运行命令:

yum install redis -y

即可,安装完成后默认启动redis服务器。
2.安装完成之后都需要把redis.conf文件中的bind 127.0.0.1注释掉
这里写图片描述
修改后,重启redis服务器
systemctl restart redis

3.centos中的redis需要设置密码,用于win10的redis desktop远程连接:
这里写图片描述

4.用Redis Desktop Manager连接Redis(CentOS):

这里写图片描述
可参考:https://www.cnblogs.com/h-change/p/6077874.html

分布式原理:

scrapy-redis实现分布式,其实从原理上来说很简单,这里为描述方便,我们把自己的核心服务器称为master,而把用于跑爬虫程序的机器称为slave。

我们知 道,采用scrapy框架抓取网页,我们需要首先给定它一些start_urls,爬虫首先访问start_urls里面的url,再根据我们的具体逻辑,对里面的元素、或者是其他的二级、三级页面进行抓取。而要实现分布式,我们只需要在这个starts_urls里面做文章就行了。

我们在master上搭建一个redis数据库(注意这个数据库只用作url的存储,不关心爬取的具体数据,不要和后面的mongodb或者mysql混淆),并对每一个需要爬取的网站类型,都开辟一个单独的列表字段。通过设置slave上scrapy-redis获取url的地址为master地址。这样的结果就是,尽管有多个slave,然而大家获取url的地方只有一个,那就是服务器master上的redis数据库。

并且,由于scrapy-redis自身的队列机制,slave获取的链接不会相互冲突。这样各个slave在完成抓取任务之后,再把获取的结果汇总到服务器上(这时的数据存储不再在是redis,而是mongodb或者 mysql等存放具体内容的数据库了)

这种方法的还有好处就是程序移植性强,只要处理好路径问题,把slave上的程序移植到另一台机器上运行,基本上就是复制粘贴的事情。

分析思路:

1.使用两台机器,一台是win10,一台是centos7的服务器,分别在两台机器上部署scrapy来进行分布式抓取一个网站.
2.centos7的ip地址为139.199.57.248,用来作为redis的slave端,win10的机器作为master.
3.master的爬虫运行时会把提取到的url封装成request放到redis中的数据库:“dmoz:requests”,并且从该数据库中提取request后下载网页,再把网页的内容存放到redis的另一个数据库中“dmoz:items”.
4.slave从master的redis中取出待抓取的request,下载完网页之后就把网页的内容发送回master的redis.
5.重复上面的3和4,直到master的redis中的“dmoz:requests”数据库为空,再把master的redis中的“dmoz:items”数据库写入到mongodb中.
6.master里的reids还有一个数据“dmoz:dupefilter”是用来存储抓取过的url的指纹(使用哈希函数将url运算后的结果),是防止重复抓取的.

实现步骤:

1.先从Github上把前几天写的代码,clone到本地:

git clone https://github.com/dik111/Zhihu.git

2.新建分支,以便不影响之前的代码:

git checkout -b distributed#新建分支
git branch#切换到分支

3.修改setting.py文件:

SCHEDULER = "scrapy_redis.scheduler.Scheduler"#修改调度器
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"#用于去重的class
 'scrapy_redis.pipelines.RedisPipeline': 301#爬取结果存储到Redis
REDIS_URL = 'redis://root:123456@139.199.57.248:6379'

执行爬虫程序,可以看到Redis中多了zhihu这个文件
这里写图片描述
这里写图片描述

其中zhihu:dupefilter就是上文所说的用来存储抓取过的url的指纹(使用哈希函数将url运算后的结果),是防止重复抓取的。

4.把分支代码更新到Github:

git status
git add -A
git commit -m "add distributed"
git push origin distributed

5.把代码部署到服务器:
5.1首先打开mongodb的配置文件mongodb.conf,把blind1270.0.1注释掉,以便远程连接mongodb。
5.2在linux系统下创建新的文件夹,并且把项目clone下来。

sudo git clone https://github.com/Germey/Zhihu.git -b distributed

6.运行爬虫程序

scrapy crawl zhihu

到这里一个简单的分布式框架已经搭建完成啦!

7.因为已经远程连接了mongodb,因此主机上面的redis已经不需要把从机的数据远程过来了,所以把之前的redis pipelines注释掉

#'scrapy_redis.pipelines.RedisPipeline': 301

相关进阶

在上面的例子中,我们是用git来更新部署代码的,但是当主机非常多的时候,这样的操作显示有点繁琐,因此,在这里我推荐使用scrapyd来进行分布式的部署。
这里写图片描述

1.安装scrapyd:

pip install scrapyd

2.启动scrapyd,并且访问远程端口:
这里写图片描述
3.修改scrapy.cfg文件:

url = http://http://127.0.0.1:6800/addversion.json
project = zhihuuser

4.安装scrapyd_client
5.启动:scrapyd-deploy
这里写图片描述
更多相关的用法请到:http://scrapyd.readthedocs.io/en/stable/

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是关于如何基于Python、ScrapyRedis和Rule组件实现分布式爬虫爬取京东华为笔记本的。首先,您需要安装ScrapyRedis,并在Scrapy的配置文件中添加Redis相关的配置: ```python # 在settings.py中添加以下配置 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" SCHEDULER = "scrapy_redis.scheduler.Scheduler" SCHEDULER_PERSIST = True REDIS_URL = 'redis://localhost:6379' ``` 然后,您需要编写Spider和Item Pipeline,其中Spider负责解析并抓取网页,Item Pipeline负责处理抓取到的数据。下面是一个示例的Spider代码: ```python from scrapy_redis.spiders import RedisSpider from scrapy.selector import Selector from ..items import ProductItem class JdSpider(RedisSpider): name = 'jd' redis_key = 'jd:start_urls' def parse(self, response): sel = Selector(response) products = sel.xpath('//div[@class="gl-i-wrap"]') for product in products: item = ProductItem() item['name'] = product.xpath('div[@class="p-name"]/a/em/text()').extract_first() item['price'] = product.xpath('div[@class="p-price"]/strong/i/text()').extract_first() item['url'] = product.xpath('div[@class="p-name"]/a/@href').extract_first() yield item ``` 在Item Pipeline中,您可以对抓取到的数据进行清洗和存储,下面是一个示例的Item Pipeline代码: ```python import pymongo class JdPipeline(object): def __init__(self, mongo_uri, mongo_db): self.mongo_uri = mongo_uri self.mongo_db = mongo_db @classmethod def from_crawler(cls, crawler): return cls( mongo_uri=crawler.settings.get('MONGO_URI'), mongo_db=crawler.settings.get('MONGO_DATABASE', 'items') ) def open_spider(self, spider): self.client = pymongo.MongoClient(self.mongo_uri) self.db = self.client[self.mongo_db] def close_spider(self, spider): self.client.close() def process_item(self, item, spider): self.db['products'].insert(dict(item)) return item ``` 最后,您需要创建一个Redis队列,并向队列中添加起始URL,如下所示: ```python import redis r = redis.Redis(host='localhost', port=6379) r.lpush('jd:start_urls', 'https://search.jd.com/Search?keyword=%E5%8D%8E%E4%B8%BA%E7%AC%94%E8%AE%B0%E6%9C%AC&enc=utf-8') ``` 最终,您就可以运行分布式爬虫并抓取京东华为笔记本的数据了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值