1、配置redis服务器允许远程连接
配置参考地址:https://www.cnblogs.com/masonblog/p/12726914.html
2. 配置setting 文件
""" scrapy-redis配置 """
# 调度器类
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 指纹去重类
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
SCHEDULER_PERSIST = True
# Redis服务器地址
REDIS_URL = "redis://127.0.0.1:6379/1" # Redis默认有16库,/1的意思是使用序号为2的库,默认是0号库(这个可以任意)
开启爬虫
项目 说明
-
豆瓣电影top250 使用scrapyredis 分布式爬虫 进行, 爬取,
-
爬取 标题,图片
-
在节点1,2开启 (此时爬虫并未开始,而是等待Redis中
top250:start_urls http://xxxxx
因为 douban 爬虫 继承Redisspider 我们没有传入 start_urls
原因: 这个项目 实现的是分布式,也就意味着在其他节点 (服务器) 上,也是相同的,会出现爬取重复的 start_urls中的url ,这是没有必要的
-
我们需在 redis客户端 输入 push指令开启 爬虫 才是 真正开始(注意一定要选择setting.py 文件中的配置的数据库)
$redis > select 2 $redis > lpush top250:start_urls https://movie.douban.com/top250?start=0&filter=
-
此时 我们需要 把数据 合在一起,方案是 存入redis 中,
通过中间件 会将信息Item 存储在Redis中
-
我们从redis 中取出数据
import base64 import csv import json import os import redis def main(): # 指定Redis数据库信息 redis_cli = redis.StrictRedis(host='127.0.0.1', port=6379, db=5) # 判断是否存在download文件夹,如果没有则创建 download_path = os.getcwd() + '/download/' # 当前文件夹下的download文件夹 if not os.path.exists(download_path): # 判断文件夹或文件 os.makedirs(download_path) while True: # FIFO模式为 blpop,LIFO模式为 brpop,获取键值 source, data = redis_cli.blpop(["top250:items"]) item = json.loads(data.decode()) # data.decode()目的,因为从Redis中提取到的数据时byte类型,所以转换为字符串类型 msg_type = item.get("type") if msg_type == "info": # # 信息 # { # "type": "info", # "img_src": img_src, # "title": title, # "rating_num": rating_num, # "people_num": people_num # } # 如果是信息,就保存到csv文件 with open(download_path + '豆瓣电影TOP250.csv', 'a') as f: # 创建一个csv的DictWriter对象,这样才能够将写入csv格式数据到这个文件 f_csv = csv.DictWriter(f, ['title', 'img_src', 'rating_num', 'people_num']) # 写入多行行(当做数据) item.pop("type") # 删除type 这个key-value f_csv.writerows([item]) print("保存信息到CSV....ok") elif msg_type == "img": # 存储图片 with open(download_path + item.get("img_name"), "wb") as f: img_data = base64.b64decode(item.get("img_bytes")) f.write(img_data) print("保存图片ok....") if __name__ == '__main__': main()
-
注意: 其中redis 不允许存入二进制数据
而 我们爬取到的图片 却是二进制数据,
我们通过base64 转换 存入redis数据库中,
Python base64与图片之间的转换https://blog.csdn.net/qq_34449006/article/details/84312550