概述

什么是分布式爬虫

  • 需要搭建一个由n台电脑组成的机群,然后在每一台电脑中执行同一组程序,让其对同一网络资源进行联合且分布的数据爬取。

原生Scrapy无法实现分布式的原因

  1. 原生Scrapy中调度器不可以被共享

    • 每一台机器都拥有一个调度器,如果一个机群共享一个调度器就可以了。
  2. 原生Scrapy中管道不可以被共享
    • 每一台机器都拥有自己的管道,如果把Item发送到同一个管道就可以了。

Scrapy_redis组件的作用是什么?

  • 提供可以被共享的管道和调度器

分布式的实现流程

实现分布式的重点在于配置

  • 环境的安装

    • pip install scrapy-redis
  • 创建工程

    • 基于Spider: scrapy genspider crawl spiderName
    • 基于CrawlSpider: scrapy genspider -t crawl spiderName
  • cd 工程

  • 创建爬虫文件

    • 基于Spider
    • 基于CrawlSpider
  • 修改爬虫文件:

    • 导包:

      • from scrapy_redis.spiders import RedisCrawlSpider 基于 CrawlSpider 爬虫文件
      • from scrapy_redis.spiders import RedisSpider 基于Spider爬虫文件
    • 将父类修改为 RedisCrawlSpider 或 RedisSpider
    • 删除 allowed_domains 和 start_urls
    • 添加 redis_key = ‘队列名称’ :可被共享的调度器队列的名称,向这个队列中放入起始url
    • 根据常规形式编写爬虫文件后续的代码
  • 修改settings配置

    • 指定管道

      1
      2
      3
      ITEM_PIPELINES = {
      'scrapy_redis.pipelines.RedisPipeline': 400
      }
  • 指定调度器

    1
    2
    3
    4
    5
    6
    # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 使用scrapy-redis组件自己的调度器
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
    SCHEDULER_PERSIST = True
  • 指定redis数据库

    1
    2
    REDIS_HOST = '192.168.13.254'
    REDIS_PORT = 6379
  • 修改redis的配置文件

    • 关闭默认绑定

      • 56行 注释 bind 127.0.0.1
    • 关闭保护模式
      • 75行 protected-mode no
      • 这样就可以写数据了
  • 启动redis的服务端(携带配置文件)和客户端

    • redis-server.exe redis.windows.conf
  • 启动分布式的程序:

    • 启动之后才会有调度器对象和队列
    • scrapy runspider xxx.py
    • 启动后在等起始url
  • 向调度器的队列中扔入一个起始的url

    • 队列是存在于redis中
    • redis的客户端中:lpush sun www.xxx.com
  • 在redis中就可以查看爬取到的数据

例子

使用Scrapy + Scrapy-redis 组件实现的分布式爬取(阳光热线问政平台的投诉帖子)的主题、状态和详细内容

地址为:http://wz.sun0769.com/html/top/reply.shtml

scrapy startproject fbsPro 创建基于fbsPro的工程

scrapy genspider -t crawl fbs 域名 创建名为fbs的spider文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# fbs.py
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule from scrapy_redis.spiders import RedisCrawlSpider
# from scrapy_redis.spiders import RedisSpider
from fbsPro.items import Item1, Item2 class FbsSpider(RedisCrawlSpider):
name = 'fbs'
# allowed_domains = ['www.xxx.com']
# start_urls = ['http://www.xxx.com/']
redis_key = 'fbs' # 可被共享的调度器队列的名称,向这个队列中放入起始url start_urls = ['http://wz.sun0769.com/html/top/reply.shtml']
# 链接提取器(如:获得每一个页码)
link = LinkExtractor(allow=r'page=\d+') # 空的话取所有url
link_1 = LinkExtractor(allow=r'page=$') # 拿到第一页数据
link_detail = LinkExtractor(allow=r'question/\d+/\d+\.shtml') # 拿到第一页数据 . 需要转义 rules = (
# 实例化一个Rule(规则解析器)对象
Rule(link, callback='parse_item', follow=False),
Rule(link_1, callback='parse_item'),
Rule(link_detail, callback='parse_detail'),
# follow = True; 将链接提取器 继续作用到 连接提取器提取到的链接 所对应的 页码源码中
) # 数据解析: 用来解析连接提取器提取到的链接所对应的页码
def parse_item(self, response):
# tr_list = response.xpath('/html/body/div[8]/table[2]/tbody/tr') # xpath中不能含有tbody
tr_list = response.xpath('/html/body/div[8]/table[2]//tr') for tr in tr_list:
title = tr.xpath('./td[3]/a[1]/text()').extract_first()
status = tr.xpath('./td[4]/span/text()').extract_first()
num = tr.xpath('./td[1]/text()').extract_first()
# print(num, title,status)
item = Item2()
item['title'] = title
item['status'] = status
item['num'] = num
yield item
# print(response) # 解析详情页中的新闻内容
def parse_detail(self, response):
content = response.xpath('/html/body/div[9]/table[2]//tr[1]/td//text()').extract()
if content:
content = ''.join(content)
num = response.xpath('/html/body/div[9]/table[1]//tr/td[2]/span[2]').extract_first().split(':')[-1].replace(
r'</span>', '')
# print(num, content)
item = Item1()
item['content'] = content
item['num'] = num
yield item

定义Item

1
2
3
4
5
6
7
8
9
10
11
12
13
# items.py
import scrapy class Item1(scrapy.Item):
# define the fields for your item here like:
content = scrapy.Field()
num = scrapy.Field() class Item2(scrapy.Item):
# define the fields for your item here like:
title = scrapy.Field()
status = scrapy.Field()
num = scrapy.Field()

配置settings.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#指定管道
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 400
}
#指定调度器
# 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
SCHEDULER_PERSIST = True #指定redis
REDIS_HOST = '192.168.13.254'
REDIS_PORT = 6379

Scrapy+redis实现分布式爬虫的更多相关文章

  1. 基于Python,scrapy,redis的分布式爬虫实现框架

    原文  http://www.xgezhang.com/python_scrapy_redis_crawler.html 爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色.相比于其他 ...

  2. scrapy如何实现分布式爬虫

    使用scrapy爬虫的时候,记录一下如何分布式爬虫问题: 关键在于多台主机协作的关键:共享爬虫队列 主机:维护爬取队列从机:负责数据抓取,数据处理,数据存储 队列如何维护:Redis队列Redis 非 ...

  3. scrapy——7 scrapy-redis分布式爬虫,用药助手实战,Boss直聘实战,阿布云代理设置

    scrapy——7 什么是scrapy-redis 怎么安装scrapy-redis scrapy-redis常用配置文件 scrapy-redis键名介绍 实战-利用scrapy-redis分布式爬 ...

  4. 阿里云Centos7.6上面部署基于redis的分布式爬虫scrapy-redis将任务队列push进redis

    Scrapy是一个比较好用的Python爬虫框架,你只需要编写几个组件就可以实现网页数据的爬取.但是当我们要爬取的页面非常多的时候,单个服务器的处理能力就不能满足我们的需求了(无论是处理速度还是网络请 ...

  5. 基于scrapy框架的分布式爬虫

    分布式 概念:可以使用多台电脑组件一个分布式机群,让其执行同一组程序,对同一组网络资源进行联合爬取. 原生的scrapy是无法实现分布式 调度器无法被共享 管道无法被共享 基于 scrapy+redi ...

  6. 在阿里云Centos7.6上面部署基于Redis的分布式爬虫Scrapy-Redis

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_83 Scrapy是一个比较好用的Python爬虫框架,你只需要编写几个组件就可以实现网页数据的爬取.但是当我们要爬取的页面非常多的 ...

  7. Python36 使用Redis 构建分布式爬虫(未完)

    很长时间未更新了,人懒了. 最近有不少的东西,慢慢写吧,最近尝试了一下python 使用Redis 来构建分布式爬虫: 单体爬虫有很多缺点,但是在学习过程中能够学习爬虫的基本理念与运行模式,在后期构建 ...

  8. Scrapy 教程(八)-分布式爬虫

    scrapy 本身并不是一个分布式框架,而 Scrapy-redis 库使得分布式成为可能: Scrapy-redis 并没有重构框架,而是基于redis数据库重写了框架的某些组件. 分布式框架要解决 ...

  9. 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码

    第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...

随机推荐

  1. iview 如何在表格中给操作图标添加Tooltip文字提示?

    项目需要用到的iview 表格中操作项目有各种各样的图标,而各种各样的图标代表不同的操作,面对新用户可能很懵,那如何给这些图标添加Tooltip文字提示? 废话不多讲,直接看代码: <templ ...

  2. BZOJ3037 创世纪[基环树DP]

    实际上基环树DP的名字是假的.. 这个限制关系可以看成每个点有一条出边,所以就是一个内向基环树森林. 找出每个基环树的环,然后对于树的部分,做DP,设状态选或不选为$f_{x,0/1}$,则 $f_{ ...

  3. 我对line-height及vertical-align的一点理解

    张鑫旭老师在文章<我对CSS vertical-align的一些理解与认识(一)>中提到: vertical-align:middle属性的表现与否,仅仅与其父标签有关,至于我们通常看到的 ...

  4. 01_Deepin15 下搭建python开发环境

    https://blog.csdn.net/iimpact/article/details/90239193 https://github.com/josonle/Coding-Now#Linux系统 ...

  5. MFC 可编辑文本框,MFC控件关联变量总结

    Edit Control控件,默认状态下,按回车会调用OnOK()关闭窗体.解决此bug可以,类视图中单击CMFCApplication3Dlg,下方重写OnOK(),注释掉其中的代码即可. Edit ...

  6. Python基础--基于ubuntu linux基础知识点

    part1:Python编译 1.直接在终端编译-----在ubuntu中Python是在home文件夹下的,输入Python(Python2编译,想要Python3直接输入python3) 一般推荐 ...

  7. Java进阶知识13 Hibernate查询语言(HQL),本文以hibernate注解版为例讲解

    1.简单概述 1.1. 1) SQL:面向的是数据库 select * from tableName;2) HQL查询(Hibernate Query language): hibernate 提供的 ...

  8. python 二维数组 转 矩阵

    x = numpy.array([[,,],[,,],[,,]]) print x print x.shape 输出 [[ ] [ ] [ ]] (3L, 3L) [Finished .2s]

  9. 【java设计模式】-02工厂模式

    工厂模式简述 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,我们在创建对象时不会对客 ...

  10. 8.5 JavaScript的BOM(二)

    8.5 JavaScript的BOM 即 浏览器对象模型(Browser Object Model) 浏览器对象包括 一.Window(窗口) 如果需要打开一个新的网站,应该通过超级链接等方式让用户主 ...