分布式爬虫
分布式爬虫
- 实现方式:scrapy+redis(scrapy结合这scrapy-redis组件)
- 原生的scrapy框架是无法实现分布式
- 需要搭建一个分布式的机群,让后让机群中的每一台电脑执行同一组程序,让其对同一组资源 进行联合且分布的数据爬取。
- 为什么原生的scrapy框架无法实现分布式
- 1.调度器无法被分布式机群共享
- 2.管道无法被分布式机群共享
- scrapy-redis组件的作用:
- 可以给原生的scrapy框架提供共享的管道和调度器
- pip install scrapy-redis
步骤:
1.修改爬虫文件
-1.1导包from scrapy_redis.spiders import RedisCrawlSpider
-1.2将源文件中的父类修改成RedisCrawlSpider
-1.3将start_url替换成redis_keys的属性,属性值为任意字符
- redis_key = 'xxx':表示的是可以被共享的调度器队列的名称,最终是需要将起始的url手动放置到 redis_key表示的队列中,所以start_url都注释了,后续需要在redis中输入网址即可
-1.4将数据解析完整即可
2.对settings.py进行配置
-
指定调度器
-
增加一个去重容器类的配置,作用使用Redis的set集合来存储请求的指纹数据,从而实现请求去重的持久化
-
直接将以下三个配置放到settings中(复制粘贴即可)
# 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 使用scrapy-redis组件自己的调度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据 SCHEDULER_PERSIST = True
-
-
指定管道(复制粘贴到settings中,不可以自定义,封装好的)
- ITEM_PIPELINES =
-
- 特点:该种管道只可以将item写入redis,(这里补充一下redis,他不能存储大文件,他是内存数据库,就算持久化他也是断电之前将数据存储在本地,然后开机就将数据加载到内存中)
-
指定redis
-
REDIS_HOST = 'redis服务的ip地址' (由于测试使用127.0.0.1的,将来使用真实的redis所在的ip地址)
-
REDIS_PORT = 6379
-
# REDIS_ENCODING = ‘utf-8’ # REDIS_PARAMS = {‘password’:’123456’} 将来redis如果有账号密码加上这个配置
3.配置redis的配置文件(redis.window.conf)
- 解除默认绑定 (意思就是允许其他ip地址的客户端远程访问)
- 56行:#bind 127.0.0.1
-
-
关闭保护模式() (保护模式就是别的客户端只能读数据,不能写数据。关闭就远程客户端可以写数据了)
-75行:protected-mode no (将yes改成no)
4.启动redis服务和客户端
5.执行scrapy工程(不要在配置文件中加入LOG_LEVEL)
启动之后你会发现项目在监听,在等,等传入起始的url加入
6.向redis_key表示的队列中添加起始url
当初咱们在spider源文件中写了redis_key了
需要在redis的客户端执行如下指令:(调度器队列是存在于redis中)
lpush sunQueue http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1
lpush 将起始的url就是你想爬取的url扔进去,没有此key会自动创建,不用担心,sunQueue千万别忘了是你的队列名字,你起的什么 就些什么
!!!当你输入完这句话后,你就会看到监听的终端会开始下载了
好的体验就是将settings中的线程数改小一点,假如你是32线程,当其他人的电脑配置特别低的话,就是调度器发布任务,抢不到资源,他就不干活了,所以你最好设置低一点的线程,当你的线程都在执行,别人电脑配置在低也能抢到资源,当然这个只是为了看效果,但是实战的时候不要将线程数改的特别低!!!!
spider源文件
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider
from fbs_project.items import FbsProjectItem
class TestSpider(RedisCrawlSpider):
name = 'test'
# allowed_domains = ['www.xxxx.com']
# start_urls = ['http://www.xxxx.com/']
redis_key='sunQueue' #可以被共享的调度器队列的名称
#稍后我们是需要将一个起始的url手动的添加到redis_key表示的队列中
rules = (
Rule(LinkExtractor(allow=r'id=1&page=\d+'), callback='parse_item', follow=True),
)
def parse_item(self, response):
# 将全站的标题获取
li_list = response.xpath('/html/body/div[2]/div[3]/ul[2]/li')
for li in li_list:
title = li.xpath('./span[3]/a/text()').extract_first()
item = FbsProjectItem()
item['title'] = title
yield item