Redis实现分布式爬虫

redis分布式爬虫

概念:多台机器上可以执行同一个爬虫程序,实现网站数据的爬取
原生的scrapy是不可以实现分布式爬虫, 原因如下:

  • 调度器无法共享
  • 管道无法共享

scrapy-redis组件:专门为scrapy开发的一套组件。 该组件可以让scrapy实现分布式 pip install scrapy-redis

分布式爬取的流程:

1 redis配置文件的配置

  •  将 bind 127.0.0.1 进行注释
  •  将 protected-mode no 关闭保护模式

2 redis服务器的开启:基于配置文件的开启

3 创建scrapy工程后, 创建基于crawlSpider的爬虫文件

4 导入RedisCrawSpider类 from scrapy_redis.spiders import RedisCrawlSpider

5 将start_url修改成redis_key = ‘xxx‘

6 解析代码编写

7 将项目的管道和调度器配置成基于scrapy-redis组件中

ITEM_PIPELINES = {
    ‘scrapy_redis.pipelines.RedisPipeline‘: 400
}
# 使用scrapy-redis组件的去重队列
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 是否允许暂停
SCHEDULER_PERSIST = True

8 配置Redis服务器地址和端口

# 如果redis服务器不在本机,则需如下配置
REDIS_HOST = ‘192.168.0.108‘
REDIS_PORT = 6379
REDIS_PARAMS = {"password":123456}

9 执行爬虫文件

scrapy runspider qiubai

10 向调度器队列中扔入一个起始url(在redis客户端中操作):lpush redis_key属性值 起始url

lpush qiubaispider https://www.qiushibaike.com/pic/

实现代码

class QiubaiSpider(RedisCrawlSpider):
    name = ‘qiubai‘
    # allowed_domains = [‘www.qiushibaike.com/pic‘]
    # start_urls = [‘http://www.qiushibaike.com/pic/‘]
    redis_key = ‘qiubaispider‘  # 表示跟start_urls含义一样
    link = LinkExtractor(allow=r‘/pic/page/\d+‘)
    rules = (
        Rule(link, callback=‘parse_item‘, follow=True),
    )

    def parse_item(self, response):
        print(‘开始爬虫‘)
        div_list = response.xpath(‘//*[@id="content-left"]/div‘)
        for div in div_list:
            print(div)
            img_url = "http://" + div.xpath(‘.//div[@class="thumb"]/a/img/@src‘).extract_first()
            item = RedisproItem()
            item[‘img_url‘] = img_url
            yield item

基于RedisSpider的分布式爬虫

案例需求:爬取的是基于文字的新闻数据(国内, 国际,军师, 航空)

  • 1 在爬虫文件中导入webdriver类
  • 2 在爬虫文件的爬虫类的构造方法中进行了浏览器实例化操作
  • 3 在爬虫类的closed方法中进行浏览器的关闭操作
  • 4 在下载中间件的process_response方法中编写执行浏览器自动化操作

wangyi.py:

middlewares.py:

from scrapy import signals
from scrapy.http import HtmlResponse
class WanyiproDownloaderMiddleware(object):
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.

    def process_request(self, request, spider):
        # Called for each request that goes through the downloader
        # middleware.

        # Must either:
        # - return None: continue processing this request
        # - or return a Response object
        # - or return a Request object
        # - or raise IgnoreRequest: process_exception() methods of
        #   installed downloader middleware will be called
        return None

    def process_response(self, request, response, spider):
        # 拦截到响应对象(下载器传递给Spider的响应对象)
        # request: 响应对象对应的请求对象
        # response: 拦截到的响应对象
        # spider: 爬虫文件对应的爬虫类的实例
        print(request.url + "这是下载中间件")
        # 响应对象中存储页面数据的篡改
        if request.url in [‘http://news.163.com/domestic/‘, ‘http://news.163.com/world/‘, ‘http://war.163.com/‘,
                           ‘http://news.163.com/air/‘]:
            spider.bro.get(url=request.url)
            js = ‘window.scrollTo(0,document.body.scrollHeight)‘
            spider.bro.execute_script(js)
            time.sleep(2)  # 一定要给与浏览器一定的缓冲加载数据的时间
            # 页面数据包含了动态加载出来的新闻数据对应的页面数据
            page_text = spider.bro.page_source
            return HtmlResponse(url=spider.bro.current_url, body=page_text, encoding=‘utf-8‘, request=request)
        else:
            return response

UA池和地址池:

from scrapy import signals
from scrapy.http import HtmlResponse
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
import random

user_agent_list = [
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 "
    "(KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 "
    "(KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 "
    "(KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 "
    "(KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 "
    "(KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 "
    "(KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 "
    "(KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 "
    "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 "
    "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]

# UA池代码的编写(单独给UA池封装一个下载中间件的一个类)
# 导包UserAgentMiddleware类
class RandomUserAgent(UserAgentMiddleware):
    def process_request(self, request, spider):
        # 从列表中随机抽选一个ua值
        ua = random.choice(user_agent_list)
        # ua值进行当前拦截到请求的ua的写入操作
        request.headers.setdefault(‘User-Agent‘, ua)

# 可被选用的代理IP
PROXY_http = [
    ‘153.180.102.104:80‘,
    ‘195.208.131.189:56055‘,
]
PROXY_https = [
    ‘120.83.49.90:9000‘,
    ‘95.189.112.214:35508‘,
]

# 批量对拦截到的请求进行IP更换
class Proxy(object):
    def process_request(self, request, spider):
        # 对拦截到请求的url进行判断(协议头到底是http还是https)
        # request.url返回值:http://www.xxx.com
        h = request.url.split(‘:‘)[0]  # 请求的协议头
        if h == ‘https‘:
            ip = random.choice(PROXY_https)
            request.meta[‘proxy‘] = ‘https://‘ + ip
        else:
            ip = random.choice(PROXY_http)
            request.meta[‘proxy‘] = ‘http://‘ + ip

基于RedisSpider实现分布式爬虫步骤

1 导包:from scrapy_redis.spiders import RedisSpider
2 将爬虫类的父类修改成RedisSpider
3 将起始URL列表注释, 添加一个redis_key(调度器队列的名称)的属性
4 进行redis数据库配置文件的配置:

  • 将 bind 127.0.0.1 进行注释
  • 将 protected-mode no 关闭保护模式

5 settings中配置redis

REDIS_HOST = ‘192.168.0.108‘
REDIS_PORT = 6379
REDIS_PARAMS = {"password": 123456}

# 使用scrapy-redis组件的去重队列
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 是否允许暂停
SCHEDULER_PERSIST = True

ITEM_PIPELINES = {
    ‘scrapy_redis.pipelines.RedisPipeline‘: 400
}

6  执行爬虫文件

scrapy runspider wangyi.py

7 向调度器的管道中扔一个起始url

lpush wangyi https://news.163.com/

原文地址:https://www.cnblogs.com/harryblog/p/11376864.html

时间: 2024-11-14 19:36:23

Redis实现分布式爬虫的相关文章

redis之分布式爬虫

分布式爬虫一般最少需要三台机器,一台为主服务器,用于生产爬虫任务,其它服务器用于消费爬虫任务. 准备爬取妹子图,主页地址 主服务器生产爬取任务 getUrlList.py #!/usr/bin/env python # _*_ coding:utf-8 _*_ __Author__ = 'KongZhaGen' import requests import bs4 import redis def creUrlList(): # 连接到redis服务器,需要密码 r = redis.Redis(

基于requests+redis的分布式爬虫

简单的网络爬虫是对一个url进行请求,并等待其返回响应.在数据量小的情况下很实用,但是当你的数据量很大,显然分布式爬虫就更占优势!关于分布式,一般是使用一台主机(master)充当多个爬虫的共享redis队列,其他主机(slave)采用远程连接master,关于redis如何安装,这里不多做介绍! 以爬虫伯乐在线的python文章为例,我的分布式爬虫由main01 main02 main03三个python文件构成,main01的主要任务是运行在master上,将文章的url爬取下来存入redi

基于Python使用scrapy-redis框架实现分布式爬虫 注

注:本文是在http://www.111cn.net/sys/CentOS/63645.htm,http://www.cnblogs.com/kylinlin/p/5198233.html的基础上加以改动的!版权归alex.shu,kylinlin所有. 1.首先介绍一下:scrapy-redis框架 scrapy-redis:一个三方的基于redis的分布式爬虫框架,配合scrapy使用,让爬虫具有了分布式爬取的功能.github地址: https://github.com/darkrho/s

基于Redis的三种分布式爬虫策略

前言: 爬虫是偏IO型的任务,分布式爬虫的实现难度比分布式计算和分布式存储简单得多. 个人以为分布式爬虫需要考虑的点主要有以下几个: 爬虫任务的统一调度 爬虫任务的统一去重 存储问题 速度问题 足够"健壮"的情况下实现起来越简单/方便越好 最好支持"断点续爬"功能 Python分布式爬虫比较常用的应该是scrapy框架加上Redis内存数据库,中间的调度任务等用scrapy-redis模块实现. 此处简单介绍一下基于Redis的三种分布式策略,其实它们之间还是很相似

Python3分布式爬虫(scrap+redis)基础知识和实战详解

背景 随着业务需求的变化,大规模爬虫遇到各种问题.python爬虫具有先天优势,社区资源比较齐全,各种框架也完美支持.爬虫性能也得到极大提升.本次分享从基础知识入手,涉及python 的两大爬虫框架pyspider.scrapy,并基于scrapy.scrapy-redis 做了分布式爬虫的介绍(直接粘贴的ppt截图)会涉及 redis.mongodb等相关知识. 一.前沿 1.1 爬虫是什么? 网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本.

【Python3爬虫】爬取美女图新姿势--Redis分布式爬虫初体验

一.写在前面 之前写的爬虫都是单机爬虫,还没有尝试过分布式爬虫,这次就是一个分布式爬虫的初体验.所谓分布式爬虫,就是要用多台电脑同时爬取数据,相比于单机爬虫,分布式爬虫的爬取速度更快,也能更好地应对IP的检测.本文介绍的是利用Redis数据库实现的分布式爬虫,Redis是一种常用的菲关系型数据库,常用数据类型包括String.Hash.Set.List和Sorted Set,重要的是Redis支持主从复制,主机能将数据同步到从机,也就能够实现读写分离.因此我们可以利用Redis的特性,借助req

【Python3爬虫】学习分布式爬虫第一步--Redis分布式爬虫初体验

一.写在前面 之前写的爬虫都是单机爬虫,还没有尝试过分布式爬虫,这次就是一个分布式爬虫的初体验.所谓分布式爬虫,就是要用多台电脑同时爬取数据,相比于单机爬虫,分布式爬虫的爬取速度更快,也能更好地应对IP的检测.本文介绍的是利用Redis数据库实现的分布式爬虫,Redis是一种常用的菲关系型数据库,常用数据类型包括String.Hash.Set.List和Sorted Set,重要的是Redis支持主从复制,主机能将数据同步到从机,也就能够实现读写分离.因此我们可以利用Redis的特性,借助req

java-爬虫-14-采用Redis创建url仓库,实现分布式爬虫

前言 使用之前单应用的队列仓库存储抓取的url存在以下两个弊端: 单应用时候,加入服务宕机了,则单应用中的队列仓库里面的url就会为空,则此时就会从页面的首页重新抓取 在加快爬虫抓取速度时候,我们有时候需要部署多节点,实现多节点抓取,加快抓取速度,但是多节点抓取同一个页面时候,怎样保证哪些url已经抓取了,而不需要再次抓取了,此时如果是单应用队列仓库将会不能区分 使用redis创建的url仓库(公共的仓库) 恰好解决了这个问题 多节点可以实现负载均衡,可以保证服务稳定性(其中一个挂掉了,不会对其

使用AKKA做分布式爬虫的思路

上周公司其他小组在讨论做分布式爬虫,我也思考了一下,提了一个方案,就是使用akka分布式rpc框架来做,自己写master和worker程序,client向master提交begin任务或者其它爬虫需求,master让worker去爬网页,worker都是kafka的同一个group然后从kafka里面拉取数据(URL),然后处理爬了的网页,解析内容,把爬下来的网页通过正则表达式匹配出嵌套的网页,然后请求actor判断是否爬过(防止生成有向图,让其变成树形结构)(这里应该是个单独的actor,这