scrapy-redis分布式爬蟲


一、概述

scrapy-redis簡介

scrapy-redis是scrapy框架基於redis數據庫的組件,用於scrapy項目的分布式開發和部署。

有如下特征:

1. 分布式爬取

  您可以啟動多個spider工程,相互之間共享單個redis的requests隊列。最適合廣泛的多個域名網站的內容爬取。

2. 分布式數據處理

  爬取到的scrapy的item數據可以推入到redis隊列中,這意味着你可以根據需求啟動盡可能多的處理程序來共享item的隊列,進行item數據持久化處理

3. Scrapy即插即用組件

  Scheduler調度器 + Duplication復制 過濾器,Item Pipeline,基本spider

 

scrapy-redis架構

scrapy-redis整體運行流程如下:

1. 首先Slaver端從Master端拿任務(Request、url)進行數據抓取,Slaver抓取數據的同時,產生新任務的Request便提交給 Master 處理;

2. Master端只有一個Redis數據庫,負責將未處理的Request去重和任務分配,將處理后的Request加入待爬隊列,並且存儲爬取的數據。

Scrapy-Redis默認使用的就是這種策略,我們實現起來很簡單,因為任務調度等工作Scrapy-Redis都已經幫我們做好了,我們只需要繼承RedisSpider、指定redis_key就行了。

缺點是,Scrapy-Redis調度的任務是Request對象,里面信息量比較大(不僅包含url,還有callback函數、headers等信息),

可能導致的結果就是會降低爬蟲速度、而且會占用Redis大量的存儲空間,所以如果要保證效率,那么就需要一定硬件水平。

 

scrapy-redis安裝

通過pip安裝即可:pip install scrapy-redis

一般需要python、redis、scrapy這三個安裝包

官方文檔:https://scrapy-redis.readthedocs.io/en/stable/

源碼位置:https://github.com/rmax/scrapy-redis

參考博客:https://www.cnblogs.com/kylinlin/p/5198233.html

 

scrapy-redis常用配置

一般在配置文件中添加如下幾個常用配置選項:

1(必須). 使用了scrapy_redis的去重組件,在redis數據庫里做去重

 

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

 

2(必須). 使用了scrapy_redis的調度器,在redis里分配請求

SCHEDULER = "scrapy_redis.scheduler.Scheduler"

 

3(可選). 在redis中保持scrapy-redis用到的各個隊列,從而允許暫停和暫停后恢復,也就是不清理redis queues

SCHEDULER_PERSIST = True

 

4(必須). 通過配置RedisPipeline將item寫入key為 spider.name : items 的redis的list中,供后面的分布式處理item 這個已經由 scrapy-redis 實現,不需要我們寫代碼,直接使用即可

ITEM_PIPELINES = {
   'scrapy_redis.pipelines.RedisPipeline': 100 ,
}

 

5(必須). 指定redis數據庫的連接參數

REDIS_HOST = '127.0.0.1' 
REDIS_PORT = 6379

 

scrapy-redis鍵名介紹

scrapy-redis中都是用key-value形式存儲數據,其中有幾個常見的key-value形式:

1、 “項目名:items”  -->list 類型,保存爬蟲獲取到的數據item 內容是 json 字符串

2、 “項目名:dupefilter”   -->set類型,用於爬蟲訪問的URL去重 內容是 40個字符的 url 的hash字符串

3、 “項目名: start_urls”   -->List 類型,用於獲取spider啟動時爬取的第一個url

4、 “項目名:requests”   -->zset類型,用於scheduler調度處理 requests 內容是 request 對象的序列化 字符串

二、scrapy-redis簡單實例

環境說明

操作系統:centos 7.6

ip地址:192.168.0.3

redis端口:6679

redis密碼:abcd@1234

說明:Master端

 

操作系統:windows 10

ip地址:192.168.0.4

python版本:3.7.9

說明:slave端

 

代碼實現

在原來非分布式爬蟲的基礎上,使用scrapy-redis簡單搭建一個分布式爬蟲,過程只需要修改一下spider的繼承類和配置文件即可,很簡單。

原非分布式爬蟲項目,參見:https://www.cnblogs.com/xiao987334176/p/13656440.html

首先修改配置文件,在settings.py文件修改pipelines,增加scrapy_redis。注意:scrapy_redis的優先級要調高

ITEM_PIPELINES = {
    'ice_cream.pipelines.IceCreamPipeline': 100,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}

 

最后一行添加如下內容:

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True

REDIS_HOST = '192.168.0.3'
REDIS_PORT = 6679
REDIS_ENCODING = 'utf-8'
REDIS_PARAMS = {'password':'abcd@1234'}

注意:請根據實際情況,修改redis連接信息

 

修改spiders文件夾下的爬蟲文件,我這里是jd.py

原文部分內容:

import scrapy
from scrapy_splash import SplashRequest
from ice_cream.items import IceCreamItem

#自定義lua腳本
lua = '''
function main(splash)
    splash:go(splash.args.url)
    splash:wait(3)
    splash:runjs("document.getElementById('footer-2017').scrollIntoView(true)")
    splash:wait(3)
    return splash:html()
    end
'''


class JdSpider(scrapy.Spider):
    name = 'jd'
    allowed_domains = ['search.jd.com']
    start_urls = ['https://search.jd.com/Search?keyword=%E5%86%B0%E6%B7%87%E6%B7%8B&enc=utf-8']
    base_url = 'https://search.jd.com/Search?keyword=%E5%86%B0%E6%B7%87%E6%B7%8B&enc=utf-8'
    # 自定義配置,注意:變量名必須是custom_settings
    custom_settings = {
        'REQUEST_HEADERS': {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
        }
    }
View Code

修改為:

import scrapy
from scrapy_splash import SplashRequest
from ice_cream.items import IceCreamItem
from scrapy_redis.spiders import RedisSpider

#自定義lua腳本
lua = '''
function main(splash)
    splash:go(splash.args.url)
    splash:wait(3)
    splash:runjs("document.getElementById('footer-2017').scrollIntoView(true)")
    splash:wait(3)
    return splash:html()
    end
'''


class JdSpider(RedisSpider):
    name = 'jd'
    allowed_domains = ['search.jd.com']
    redis_key = "jd:start_urls"
    # start_urls = ['https://search.jd.com/Search?keyword=%E5%86%B0%E6%B7%87%E6%B7%8B&enc=utf-8']
    base_url = 'https://search.jd.com/Search?keyword=%E5%86%B0%E6%B7%87%E6%B7%8B&enc=utf-8'
    # 自定義配置,注意:變量名必須是custom_settings
    custom_settings = {
        'REQUEST_HEADERS': {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
        }
    }
View Code

注意:只修改了兩個地方

一個是繼承類:由scrapy.Spider修改為RedisSpider

然后start_url已經不需要了,修改為:redis_key = "xxxxx",其中,這個鍵的值暫時是自己取的名字,

一般用項目名:start_urls來代替初始爬取的url。由於分布式scrapy-redis中每個請求都是從redis中取出來的,因此,在redis數據庫中,設置一個redis_key的值,作為初始的url,scrapy就會自動在redis中取出redis_key的值,作為初始url,實現自動爬取。

 

啟動程序

登windows10系統,先啟動爬蟲程序,執行命令:

scrapy runspider ice_cream/spiders/jd.py

注意:這里必須運行scrapy runspider命令,和之前不太一樣。

 

最后登錄centos 7.6系統,進入redis

redis-cli -p 6679

 

執行命令:

lpush jd:start_urls https://search.jd.com/Search?keyword=%E5%86%B0%E6%B7%87%E6%B7%8B&enc=utf-8

注意:jd:start_urls是在jd.py中定義的redis_key,https://search.jd.com/xxx,就是jd.py定義的start_urls,只不過被注釋掉而已。

 

執行完上面的lpush命令之后,windows10的爬蟲程序,就會開始工作。

如此一來,分布式已經搭建完畢。

 

本文只用了2台機器。如果資源足夠,可以多增加幾台slave機器,將slave機器的代碼copy過去,並運行scrapy runspider命令即可。

master端,只需要執行lpush 命令。

 

本文參考鏈接:

https://www.cnblogs.com/pythoner6833/p/9148937.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM