分佈式:
架構方式
多臺真實機器+爬蟲(如requests,scrapy等)+任務共享中心
多臺虛擬機器(或者部分虛擬部分真實)+爬蟲(如requests,scrapy等)+任務共享中心
多臺容器級虛擬化機器(或者部分真實機器)+爬蟲(如requests,scrapy等)+任務共享中心
docker+redis+requests+(mysql)
docker+redis+scrapy+scrapy-redis+r(mysql)html
中心節點:任務控制-通訊redis,數據存儲mysqlpython
rconn=redis.Redis("118.31.46.101","6379") #鏈接中心節點redis
for i in range(0,5459058):
isdo=rconn.hget("url",str(i))
if(isdo!=None): #先取出當前url判斷是否爬取過
continue
rconn.hset("url",str(i),"1") #如沒有爬過,先把url標記
try:
data=urllib.request.urlopen("http://www.17k.com/book/"+str(i)+".html").read().decode("utf-8","ignore")
except Exception as err:
print(str(i)+"----"+str(err))
continue
pat='<a class="red" .*?>(.*?)</a>'
rst=re.compile(pat,re.S).findall(data)
if(len(rst)==0):
continue
name=rst[0]
print(str(i)+"-----"+str("ok"))
rconn.hset("rst",str(i),str(name)) #當前url爬完後,把數據保存mysql
scrapy-redis
pip3 install scrapy-redisredis
scrapy-redis中queue三種方式:
SpiderQueue = FifoQueue #先進先出
SpiderStack = LifoQueue #後進先出
SpiderPriorityQueue = PriorityQueue #優先隊列,默認sql
scrapy-redis分佈式部署:
中心節點安裝redis,(mysql)
各子節點均安裝python,scrapy,scrapy-redis,python的redis模塊,(pymysql)
將修改好的分佈式爬蟲項目部署到各子節點
各子節點分別運行分佈式爬蟲項目docker
一.修改爬蟲文件
1.導入scrapy-redis模塊:from scrapy_redis.spiders import RedisSpider
2.將當前爬蟲類的父類修改爲RedisSpider
3.將allowed_domains和start_urls進行刪除
4.添加一個新的屬性redis_key = 'xxx',該屬性值表示的就是能夠被共享的調度器隊列的名稱
二.進行配置文件的配置
1.保證爬蟲文件發起的請求都會被提交到能夠被共享的調度器的隊列中
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
2.保證爬蟲文件提交的item會被存儲到能夠被共享的管道中
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 400
}
3.配置最終數據存儲的redis數據庫
REDIS_HOST = 'redis服務的ip地址'
REDIS_PORT = 6379
REDIS_ENCODING = 'utf-8'
REDIS_PARAMS = {'password':'123456dj'}
4.redis數據庫的配置文件進行配置:關閉保護模式和註釋掉bind 127.0.0.1
5.開啓redis服務和客戶端
6.執行爬蟲文件:scrapy runspider xxx.py
7.向調度器隊列中仍入一個起始的url:數據庫
settings:
#使用的是能夠被共享的調度器
# 增長了一個去重容器類的配置, 做用使用Redis的set集合來存儲請求的指紋數據, 從而實現請求去重的持久化
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis組件本身的調度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 配置調度器是否要持久化, 也就是當爬蟲結束了, 要不要清空Redis中請求隊列和去重指紋的set。若是是True, 就表示要持久化存儲, 就不清空數據, 不然清空數據
SCHEDULER_PERSIST = True架構
#使用scrapy-redis中封裝好的能夠被共享的管道
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 400
}
#配置redis
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379
REDIS_ENCODING = 'utf-8'
# REDIS_PARAMS = {‘password’:’123456’}dom