定制起始url(scrapy_redis)
爬虫:(在这里不用配置start_url,直接可以取redis里面取start_url,可以多个)
from scrapy_redis.spiders import RedisSpider
# class ChoutiSpider(scrapy.Spider):
class ChoutiSpider(RedisSpider):
name = 'baidu'##在这里设置了这个name,那么在redispider里面就可以按照这个key来找到里面对应的值(开始url,可能多个),
#key的格式是:self.redis_key = self.redis_key % {'name': self.name}
allowed_domains = ['baidu.com']
def parse(self, response):
print('执行操作')
print(response)
在settings里面的配置:
#true的话,就是集合,false的话,就为列表
REDIS_START_URLS_AS_SET=False#默认是false,列表的格式取数据出来
# REDIS_START_URLS_KEY = '%(name)s:start_urls'#不设置默认是这个,这个是存入redis里面的key,可以根据这来取value,例如:baidu:start_urls
如果是列表的话,取数据是lpop(key),key就是下面的这个
如果是集合的话,集合取数据是spop(key),例如:spop('baidu:start_urls')>>后面就是对应的全部的开始url(可以多个)
redis存入开始url:
在了一个.py文件里面存入开始url 列表:
import redis
conn=redis.Redis(host='127.0.0.1',port=6379)
conn.lpush('baidu:start_urls','http://www.baidu.com')
如果是settings里面:
REDIS_START_URLS_AS_SET=False的话,就是列表的形式,存入就是lpush或者是rpush等操作
如果是true的话,那么存入就是集合的形式,sadd等操作
集合:
import redis
conn=redis.Redis(host='127.0.0.1',port=6379)
conn.sadd('baidu:start_urls','http://www.baidu.com')##按照这个格式来存数据的
print(conn.smembers('baidu:start_urls'))
scrapy_redis里面的spider源码分析:
class RedisMixin(object):
"""Mixin class to implement reading urls from a redis queue."""
redis_key = None
redis_batch_size = None
redis_encoding = None # Redis client placeholder.
server = None def start_requests(self):
"""Returns a batch of start requests from redis."""
return self.next_requests() def setup_redis(self, crawler=None):
"""Setup redis connection and idle signal. This should be called after the spider has set its crawler object.
"""
if self.server is not None:
return if crawler is None:
# We allow optional crawler argument to keep backwards
# compatibility.
# XXX: Raise a deprecation warning.
crawler = getattr(self, 'crawler', None) if crawler is None:
raise ValueError("crawler is required") settings = crawler.settings #####去配置文件里面那这个其始url,START_URLS_KEY = '%(name)s:start_urls',如果没有配置文件的话,就读取后面部分
if self.redis_key is None:
self.redis_key = settings.get(
'REDIS_START_URLS_KEY', defaults.START_URLS_KEY,
)##在这里可以自己设置这个格式,REDIS_START_URLS_KEY在settigs里面设置成自己想要保存的格式,注意:自己就按照这个
,格式进行保存,下面就以这个格式作为键进行查找到相对应的全部的开始url self.redis_key = self.redis_key % {'name': self.name}####在这里设置这个name的redis查询的key,如果在redis里面有这个key存在的话,就取出里面的值进行查找
'''
所以可以自己在添加开始到这个name里面去,这个key格式是固定的,START_URLS_KEY = '%(name)s:start_urls'''
######写入redis的这个key里面存进去,里面可以放url,多个,然后拿到多个开始的url
if not self.redis_key.strip():
raise ValueError("redis_key must not be empty") if self.redis_batch_size is None:
# TODO: Deprecate this setting (REDIS_START_URLS_BATCH_SIZE).
self.redis_batch_size = settings.getint(
###取配置文件里面取值,后面是int的类型,转化为int的类型
'REDIS_START_URLS_BATCH_SIZE',
settings.getint('CONCURRENT_REQUESTS'),
) try:
self.redis_batch_size = int(self.redis_batch_size)
except (TypeError, ValueError):
raise ValueError("redis_batch_size must be an integer") if self.redis_encoding is None:
self.redis_encoding = settings.get('REDIS_ENCODING', defaults.REDIS_ENCODING) self.logger.info("Reading start URLs from redis key '%(redis_key)s' "
"(batch size: %(redis_batch_size)s, encoding: %(redis_encoding)s",
self.__dict__) self.server = connection.from_settings(crawler.settings)
# The idle signal is called when the spider has no requests left,
# that's when we will schedule new requests from redis queue
crawler.signals.connect(self.spider_idle, signal=signals.spider_idle) def next_requests(self):
"""Returns a request to be scheduled or none."""
use_set = self.settings.getbool('REDIS_START_URLS_AS_SET', defaults.START_URLS_AS_SET)
fetch_one = self.server.spop if use_set else self.server.lpop
##做了判断,如果是REDIS_START_URLS_AS_SET=True得话,那么就为集合
##做了判断,如果是REDIS_START_URLS_AS_SET=False得话,那么就为列表
# XXX: Do we need to use a timeout here?
found = 0
# TODO: Use redis pipeline execution.
####在下面进行寻找,如果存在这个redis_key的话,就执行,有多个就执行多个其实url, ''''
下面是一直循环着,看有没有其实url,在redis里面,这个格式是,REDIS_START_URLS_KEY = '%(name)s:start_urls'>>
当为false的时候,就是以列表的形式查找
conn.lpush('baidu:start_urls','http://www.baidu.com')
当true的时候,就是集合 '''
while found < self.redis_batch_size:
data = fetch_one(self.redis_key)##可能是spop或者是lpop
if not data:
# Queue empty.
break
req = self.make_request_from_data(data)
if req:
yield req
found += 1
else:
self.logger.debug("Request not made from data: %r", data) if found:
self.logger.debug("Read %s requests from '%s'", found, self.redis_key) def make_request_from_data(self, data):
"""Returns a Request instance from data coming from Redis. By default, ``data`` is an encoded URL. You can override this method to
provide your own message decoding. Parameters
----------
data : bytes
Message from redis. """
url = bytes_to_str(data, self.redis_encoding)
return self.make_requests_from_url(url) def schedule_next_requests(self):
"""Schedules a request if available"""
# TODO: While there is capacity, schedule a batch of redis requests.
for req in self.next_requests():
self.crawler.engine.crawl(req, spider=self) def spider_idle(self):
"""Schedules a request if available, otherwise waits."""
# XXX: Handle a sentinel to close the spider.
self.schedule_next_requests()
raise DontCloseSpider
定制起始url(scrapy_redis)的更多相关文章
- python - scrapy 爬虫框架 ( 起始url的实现,深度和优先级,下载中间件 )
1. start_urls -- 起始URL 的内部实现(将迭代器转换为生成器) class QSpider(scrapy.Spider): name = 'q' allowed_domains ...
- Scarpy 起始url 自定义代理 自定义去重规则
- start_urls - 内部原理 """ scrapy引擎来爬虫中去起始的URL: 1. 调用start_requests并获取返回值 2. v = iter(返回 ...
- Scrapy定制起始请求
Scrapy引擎来爬虫中取起始的URL 1.调用start_requests方法(父类),并获取返回值 2.将放回值变成迭代器,通过iter() 3.执行__next__()方法取值 4.把返回值全部 ...
- Scrapy-redis 组件
scrapy-redis 简介 scrapy-redis是scrapy框架基于redis数据库的组件,用于scrapy项目的分布式开发和部署. 特征 分布式爬取 可以启动多个spider工程,相互之间 ...
- Scrapy入门操作
一.安装Scrapy: 如果您还未安装,请参考https://www.cnblogs.com/dalyday/p/9277212.html 二.Scrapy基本配置 1.创建Scrapy程序 cd D ...
- scrapy_redis使用介绍
scrapy_redis是一个基于redis的scrapy组件,通过它可以快速实现简单的分布式爬虫程序,该组件主要提供三大功能: (1)dupefilter——URL去重规则(被调度器使用) (2)s ...
- iOS 打开本地 其他应用程序(URL Types)
iOS 打开本地其他应用程序(URL Types) /*前言废话:Xcode是神奇的,是我所见到的编译器中最为神奇的,如:它可以同时运行两个甚至更多Project到我们模拟器上,可以同时使用一个模拟器 ...
- ken桑带你读源码 之 scrapy_redis
首先更大家说下 正式部署上线的爬虫会有分布式爬虫的需求 而且原本scrapy 的seen (判断重复url的池 不知道用啥词 已抓url吧 ) 保存在磁盘 url 队列 也是保存在磁盘 (保 ...
- 解读Scrapy框架
Scrapy框架基础:Twsited Scrapy内部基于事件循环的机制实现爬虫的并发.原来: url_list = ['http://www.baidu.com','http://www.baidu ...
随机推荐
- 细说shiro之四:在web应用中使用shiro
官网:https://shiro.apache.org/ 1. 下载在Maven项目中的依赖配置如下: <!-- shiro配置 --> <dependency> <gr ...
- extjs.net list 点击弹出修改页面及初始化
<SaveMask ShowMask="true" /> <LoadMask ShowMask="true" /> <Listen ...
- LVS Nginx 负载均衡区别
lvs nginx haproxy 对比都可以做负载均衡:工作方式和应用场景各有特点: lvs Linux 虚拟 服务: 1.可以应用支持协议: ftp http dns telnet smtp sm ...
- [C++]Linux之虚拟文件系统[/proc]中关于CPU/内存/网络/内核等的一些概要性说明
声明:如需引用或者摘抄本博文源码或者其文章的,请在显著处注明,来源于本博文/作者,以示尊重劳动成果,助力开源精神.也欢迎大家一起探讨,交流,以共同进步- 0.0 1.Linux虚拟文件系统 首先要明白 ...
- :target方法实现切换
<!DOCTYPE HTML><html><head> <title>:target切换</title> <meta charset= ...
- 第26月第18天 mybatis_spring_mvc
1. applicationContext.xml 配置文件里最主要的配置: <?xml version="1.0" encoding="utf-8"? ...
- ES6走一波 module
ES6模块设计思想: 尽量静态化,使得编译时就能确定模块的依赖关系,输入.输出的变量.可做静态优化. ES6模块不是对象,而是通过export命令显示指定输出的代码,再通过import命令输入 ex ...
- 20165337第七周实验报告《Java面向对象程序设计》
实验报告封面 实验内容及步骤 实验一.实现百分制成绩转成"优.良.中.及格.不及格"五级制成绩的功能 代码 public class MyUtil{ public static S ...
- python,os.path简单用法
#首先导入os包 import os#引入time模块是因为需要将浮点型的时间转为东八区时间 import time # basename(path),去掉路径名称,单独返回文件名 f = os.pa ...
- Sql server—— for xml path简单用法(可以按照分组把相同组的列中的不同的值,像字符串一样拼接在一起显示在分组之后的列中。)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI8AAACWCAIAAABo2EyXAAAKeklEQVR4nO2dy27rNh7G+U7CFIrfZX