上次寫scrapy的東西還是2021年,好久沒用這東西了,記錄一下吧,以下是正文
scrapy實現分布式爬蟲scrapy-redis
概括的講:scrapy-redis是通過從同一個redis數據庫中取出多個請求分發給不同的爬蟲來實現分布式的
scrapy改成scrapy-redis只需要修改兩個文件的東西
1.spider.py
2.setting.py
1、修改spider.py
# 修改前
class Movie80Spider(scrapy.Spider):
name = "Movie80s"
allowed_domains = ["xvipvip.com"]
start_urls = ["http://www.xvipvip.com/acg/y2024/"]
# 修改后
from scrapy_redis.spiders import RedisSpider
class Movie80sSpider(RedisSpider):
name = "Movie80s"
# allowed_domains = ["xvipvip.com"]
# start_urls = ["http://www.xvipvip.com/acg/y2024/"]
redis_key = 'Movie80:start_urls'
2、修改setting.py
在setting.py內添加以下設置
""" scrapy-redis配置 """
# 1(必須). 使用了scrapy_redis的去重組件,在redis數據庫里做去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 2(必須). 使用了scrapy_redis的調度器,在redis里分配請求
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 3(必須). 是否在關閉時候保留原來的調度器和去重記錄,True=保留,False=清空
# 在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,
# 之前的管道
"movie80s.pipelines.Movie80SPipeline": 300,
}
# 5(必須). 指定redis數據庫的連接參數
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_DB = 0
# REDIS_PARAMS = {
# "password": "一只酸檸檬精",
# }
# 6.如果不啟用則按scrapy默認的策略
# -1. 默認的 按優先級排序(Scrapy默認),由sorted set實現的一種非FIFO、LIFO方式。
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue' # 使用有序集合來存儲
# -2. 可選的 按先進先出排序(FIFO)
# SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderQueue'
# -3. 可選的 按后進先出排序(LIFO)
# SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderStack'
# 7. LOG等級
#LOG_LEVEL = 'DEBUG'
# 8設置每次從 Redis 隊列中獲取的請求個數()
REDIS_START_URLS_BATCH_SIZE = 5
3、運行
第一步啟動爬蟲:
在不同的電腦上啟動爬蟲;
或者在本地不同的文件夾內復制多份爬蟲,啟動。
scrapy crawl Movie80s
爬蟲開啟后會進入監聽狀態,等待redis中存入爬取的鏈接
image.png
第二步將需要爬取的鏈接存入redis:
因為我們在setting.py中設置的redis數據庫的參數是0號數據庫,所以我們需要將爬取的鏈接存入redis的0號數據庫中
其中 Movie80:start_urls 是我們在spider.py中設置的redis_key
lpush Movie80:start_urls http://www.xvipvip.com/mov/0/11/china/1.html
爬蟲從redis中拿到需要爬取的鏈接,就開始運行了
image.png
這是爬蟲結束后存入redis的數據
Movie80s:dupefilter是開啟去重后,redis數據庫存儲已經爬取的網址的指紋,以此來確保每個網址只被爬取一次
Movie80s:items是我們在setting.py添加的第四步:《通過配置RedisPipeline將item寫入key為 spider.name : items 的redis的list中,供后面的分布式處理item》
image.png
遇到的一個問題
問題1:本地的scrapy-redis,復制了兩份,A和B兩個都開啟后,爬蟲A在跑,爬蟲B還在監聽,關閉了爬蟲A之后,爬蟲B開始運行了。
原因:請求量太少了,一個爬蟲就夠搞定了
解決辦法 :
設置每次從 Redis 隊列中獲取的請求個數,越小越好,
REDIS_START_URLS_BATCH_SIZE = 5