[scrapy-redis] 将scrapy爬虫改造成分布式爬虫 (2)
1. 修改redis设置
redis默认处在protection mode, 修改/etc/redis.conf, protected-mode no, 或者给redis设置密码,
将bind 127.0.0.1这一行用#注释掉
2. 修改爬虫设置
向settings.py加入以下设置
REDIS_URL 为master的ip加上redis的端口号
# For scrapy_redis
# Enables scheduling storing requests queue in redis.
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# Ensure all spiders share same duplicates filter through redis.
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# Don't cleanup redis queues, allows to pause/resume crawls.
SCHEDULER_PERSIST = True
# Schedule requests using a priority queue. (default)
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
# Store scraped item in redis for post-processing.
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300
}
# Specify the host and port to use when connecting to Redis (optional).
#REDIS_HOST = 'localhost'
#REDIS_PORT = 6379
# Specify the full Redis URL for connecting (optional).
# If set, this takes precedence over the REDIS_HOST and REDIS_PORT settings.
#REDIS_URL = 'redis://user:pass@hostname:9001'
REDIS_URL = 'redis://192.168.1.20:6379' #修改成自己的ip和port
3. 修改爬虫代码
- 使爬虫继承自RedisSpider
from scrapy_redis.spiders import RedisSpider
class DoubanSpider(RedisSpider):
- 增加一个
redis_key属性,这个属性就是start_urls在redis中的key - 注释掉
start_urls
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
from project_douban.items import Movie
from scrapy_redis.spiders import RedisSpider
class DoubanSpider(RedisSpider):
name = 'douban'
allowed_domains = ['douban.com']
redis_key = "doubanSpider:start_urls"
#start_urls = ['https://movie.douban.com/top250']
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent' : 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Mobile Safari/537.36',
}
custom_settings = {
'DEFAULT_REQUEST_HEADERS' : headers,
'REDIRECT_ENABLED' : 'False',
#'LOG_LEVEL' : 'WARNING',
}
def parse(self, response):
items = response.xpath('//div[@class="item"]')
for item in items:
movie = Movie()
movie['index'] = item.xpath('div//em/text()').extract_first(default = '')
self.logger.info(movie['index'])
movie['src'] = item.xpath('div//img/@src').extract_first(default = '')
self.logger.info(movie['src'])
movie['title'] = item.xpath('.//div[@class="hd"]/a/span[1]/text()').extract_first(default = '') #.xpath('string(.)').extract()).replace(' ','').replace('\xa0',' ').replace('\n',' ')
self.logger.info(movie['title'])
movie['star'] = item.xpath('.//span[@class="rating_num"]/text()').extract_first(default = '')
self.logger.info(movie['star'])
movie['info'] = item.xpath('.//div[@class="bd"]/p').xpath('string(.)').extract_first(default = '').strip().replace(' ','').replace('\xa0',' ').replace('\n',' ')
self.logger.info(movie['info'])
yield movie
next_url = response.xpath('//span[@class="next"]/a/@href').extract_first(default = '')
self.logger.info('next_url: ' + next_url)
if next_url:
next_url = 'https://movie.douban.com/top250' + next_url
yield Request(next_url, headers = self.headers)
- log写入文件(optional)
import logging
import os
import time
def get_logger(name, start_time = time.strftime('%Y_%m_%d_%H', time.localtime())):
path = '/var/log/scrapy-redis/'
# path = 'baidu_tieba.log'
if not os.path.exists(path):
os.makedirs(path)
log_path = path + start_time
# 创建一个logger
my_logger = logging.getLogger(name)
my_logger.setLevel(logging.INFO)
formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] %(filename)s[line:%(lineno)d] %(message)s', datefmt = '%Y-%m-%d %H:%M:%S')
# 创建handler,用于写入日志文件
handler_info = logging.FileHandler('%s_info.log' % log_path, 'a', encoding='UTF-8')
handler_info.setLevel(logging.INFO)
handler_info.setFormatter(formatter)
my_logger.addHandler(handler_info)
handler_warning = logging.FileHandler('%s_warning.log' % log_path, 'a', encoding='UTF-8')
handler_warning.setLevel(logging.WARNING)
handler_warning.setFormatter(formatter)
my_logger.addHandler(handler_warning)
handler_error = logging.FileHandler('%s_error.log' % log_path, 'a', encoding='UTF-8')
handler_error.setLevel(logging.ERROR)
handler_error.setFormatter(formatter)
my_logger.addHandler(handler_error)
return my_logger
Miscellaneous
RedisSpider vs RedisCrawlSpider
直接看源代码,上文本比较

| item | RedisSpider | RedisCrawlSpider |
|---|---|---|
| REDIS_START_URLS_AS_SET | default: False | default: True |
| 继承自Spider | 继承自CrawlSpider |
scrapy.Spider -> scrapy.CrawlSpider
scrapy.Spider是所有爬虫的基类, scrapy.CrawlSpider基于scrapy.Spider, 增加了rules, 可以设置某种规则,只爬取满足这些规则的网页, RedisCrawlSpider也继承了这一特性
Reference
[scrapy-redis] 将scrapy爬虫改造成分布式爬虫 (2)的更多相关文章
- Python爬虫教程-新浪微博分布式爬虫分享
爬虫功能: 此项目实现将单机的新浪微博爬虫重构成分布式爬虫. Master机只管任务调度,不管爬数据:Slaver机只管将Request抛给Master机,需要Request的时候再从Master机拿 ...
- Scrapy框架之基于RedisSpider实现的分布式爬虫
需求:爬取的是基于文字的网易新闻数据(国内.国际.军事.航空). 基于Scrapy框架代码实现数据爬取后,再将当前项目修改为基于RedisSpider的分布式爬虫形式. 一.基于Scrapy框架数据爬 ...
- 【Python3爬虫】学习分布式爬虫第一步--Redis分布式爬虫初体验
一.写在前面 之前写的爬虫都是单机爬虫,还没有尝试过分布式爬虫,这次就是一个分布式爬虫的初体验.所谓分布式爬虫,就是要用多台电脑同时爬取数据,相比于单机爬虫,分布式爬虫的爬取速度更快,也能更好地应对I ...
- 基于Python,scrapy,redis的分布式爬虫实现框架
原文 http://www.xgezhang.com/python_scrapy_redis_crawler.html 爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色.相比于其他 ...
- scrapy分布式爬虫scrapy_redis二篇
=============================================================== Scrapy-Redis分布式爬虫框架 ================ ...
- Python分布式爬虫必学框架Scrapy打造搜索引擎
Python分布式爬虫必学框架Scrapy打造搜索引擎 部分课程截图: 点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/1-wHr4dTAxfd51M ...
- 爬虫07 /scrapy图片爬取、中间件、selenium在scrapy中的应用、CrawlSpider、分布式、增量式
爬虫07 /scrapy图片爬取.中间件.selenium在scrapy中的应用.CrawlSpider.分布式.增量式 目录 爬虫07 /scrapy图片爬取.中间件.selenium在scrapy ...
- 基于scrapy框架的分布式爬虫
分布式 概念:可以使用多台电脑组件一个分布式机群,让其执行同一组程序,对同一组网络资源进行联合爬取. 原生的scrapy是无法实现分布式 调度器无法被共享 管道无法被共享 基于 scrapy+redi ...
- 聚焦Python分布式爬虫必学框架Scrapy 打造搜索引擎视频教程
下载链接:https://www.yinxiangit.com/595.html 目录: 第1章 课程介绍介绍课程目标.通过课程能学习到的内容.和系统开发前需要具备的知识 第2章 windows下搭建 ...
随机推荐
- P1726 上白泽慧音 tarjan 模板
P1726 上白泽慧音 这是一道用tarjan做的模板,要求找到有向图中最大的联通块. #include <algorithm> #include <iterator> #in ...
- HDU-3478Catch二分图的否命题
HDU-3478Catch 题意:考虑Thief能否: 由于我推着推着就想到必须要三点可以互通,和二分图的结论正好相反,所以就试了一发, 真没想到thief的初始位置是不用考虑的. 下面是ac代码: ...
- hdu 1024 Max Sum Plus Plus(简单dp)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1024 题意:给定一个数组,求其分成m个不相交子段和的最大值. 这题有点问题其实m挺小的但题目并没有给出 ...
- codeforces 361 D. Levko and Array(dp+二分)
题目链接:http://codeforces.com/contest/361/problem/D 题意:最多可以修改K次数字,每次修改一个数字变成任意值,C=max(a[i+1]-a[i]):求操作之 ...
- poj 2253 Frogger(floyd变形)
题目链接:http://poj.org/problem?id=1797 题意:给出两只青蛙的坐标A.B,和其他的n-2个坐标,任一两个坐标点间都是双向连通的.显然从A到B存在至少一条的通路,每一条通路 ...
- openlivewriter安装配置
一.前言 最近工作比较忙,同时也在构思下面我应该写哪方面的文章.上一篇文章,我直接在博客园管理后台自带的编辑器写的,确实比较麻烦,于是我就打算使用官方推荐的客户端“Open Live Writer”. ...
- ResourceDictionary主题资源替换(二) :通过加载顺序来覆盖之前的主题资源
之前的ResourceDictionary主题资源替换(一)通过加载顺序来覆盖之前的主题资源,介绍了WPF框架对ResourceDictionary资源的合并规则. 此篇介绍一种在编译期间,实现资源替 ...
- Appium+python自动化(三十七)- 士兵突击许三多 - 多个appium服务启动,多个设备启动,多进程并发启动设备-并发测试 - 下(超详解)
简介 接着上一篇继续看一下如何并发测试以及并发测试的过程中,可能遇到的问题,在这里宏哥把宏哥遇到的和小伙伴或者童鞋们,一起分享一下. Appium端口检测 问题思考 经过前面学习,我们已经能够使用py ...
- 增删改查——Statement接口
1.增加数据表中的元组 package pers.datebase.zsgc; import java.sql.Connection; import java.sql.DriverManager; i ...
- Linux 笔记 - 第十三章 Linux 系统日常管理之(四)Linux 中 rsync 工具和网络配置
博客地址:http://www.moonxy.com 一.前言 rsync 命令是一个远程数据同步工具,可通过 LAN/WAN 快速同步多台主机间的文件,可以理解为 remote sync(远程同步) ...