scrapy中的设置及内置服务
Scrapy框架有两个主要的对象Reques与Response
具体内容看官网https://www.osgeo.cn/scrapy/topics/spider-middleware.html?highlight=%E4%B8%AD%E9%97%B4%E4%BB%B6
他们贯穿在爬虫的始终,最终爬虫通过他们将数据串联起来。
Request对象是在Spider中生成,包含HTTP请求信息,在框架中经过一系列传递、处理,最终达到Downloader下载器,下载器执行Request中的请求进行数据抓取,将生成的响应包装成一个Response对象,在经过传送处理,最终返回到发送Request的Spider中。
爬虫Spider中间件是用来处理Response响应的,而Downloader中间件是用来处理Request请求的。
激活中间件:
启用Spider中间件时,需要将其加入SPIDER_MIDDLEWARES设置中。该设置位于settings.py文件中,是字典类型对的,其中键为中间件的路径,值为中间件的顺序。
启用中间件的有序列表:
第一个中间件是最靠近引擎的,最后一个中间件是最靠近Spider的。
一般自定义中间件在500-700之间最为妥当。
如果要禁用中间件,可以将中间件的值赋为None,键还是中间件的路径,修改的是中间件的顺序。
DOWNLOADER_MIDDLEWARES = {
'lianjiahouse.middlewares.LianjiahouseDownloaderMiddleware': 543,
}
编写Spider中间件
中间件与管道类似,每个中间件组件都实现了以下一个或多个方法的Python类。
1.process_spider_input(response,spider)
说明:
当参数response通过参数spider中间件时,该方法被调用,处理该rsponse,即在下载器中间件处理完成后,马上要进入某个回调函数parse_xx()前被调用。
参数:
response(Response对象):被处理的Response
spider(Spider对象):该Response对应的Spider
返回值:
该方法返回一个None或者抛出一个异常。如果其返回None,Scrapy江会继续处理该Response,调用所有其他的中间件直到Spider处理该Response。如果其抛出一个异常,Scrapy将不会调用其他中间件的process_spider_input()方法,而是调用Request的errback。errback的输出将会从另一个方向被重新输入中间件链中,使用process_spider_output()方法来处理,当期抛出异常时调用procrss_spider_execption().
2.process_spider_output(response,result,spider)
当Spider处理完毕Response返回result时,即在爬虫运行yield item或者yield scrapy.Request()的时候调用该方法
这些因该都是内置的中间件方法
,好像不是,是要自己模仿这样写
3.process_spider_exception(response,exception,spider)
说明:当spider或其他spider中间件的process_spider_input()抛出异常时,该方法被调用。
参数:
response:异常抛出时处理的Response
exception:抛出异常
spider:抛出异常的Spider
返回值:
该方法必须返回一个None或者一个包含Response或Item对象的可迭代对象(iterable)
如果返回None,Scrapy将继续处理该异常,调用中间件链中的其他中间件的process_spider_exception()方法,直到所有中间件都被调用,该异常到达引擎(异常将被记录并被忽略)
如果其返回一个可迭代对象,那么中间件链的process_spider_output()方法将被调用,其他的中间件的process_spider_exception()将不会被调用。
4.process_start_request(start_request,spider)
说明:
该方法以Spider启动的Request为参数被调用
参数
start_request(包含Request的可迭代对象):start request列表
spider(Spider对象):启动start request的Spider
返回值:
该方法接收的是一个可迭代对象(start_requests参数),而且必须返回一个包含Request对象的可迭代对象。
Spider内置中间件
Spider已经内置了一些可以辅助爬取的中间件,通过这些中间件的启用、配置可以方便的进行爬虫的优化,提高爬取成功功率与效率。
DepthMiddleware爬取深度中间件
作用:他是一个用于追踪被爬取网站中每个Request的爬取深度的中间件。深度是start_urls中定义URL的相对值,也就是相对URL的深度。
他可用于限制爬取的最大深度,并根据深度控制请求优先级等。
classscrapy.spidermiddlewares.depth.DepthMiddleware[源代码]¶
DepthmIddleware用于跟踪被擦除站点内每个请求的深度。它通过设置工作 request.meta['depth'] = 0 如果之前没有设置值(通常只是第一个请求),则将其递增1。
它可以用来限制要抓取的最大深度,根据深度控制请求优先级,等等。
这个 DepthMiddleware 可以通过以下设置进行配置(有关详细信息,请参阅设置文档):
DEPTH_LIMIT -允许对任何网站进行爬网的最大深度。如果为零,则不施加限制。
DEPTH_STATS_VERBOSE -是否收集每个深度的请求数。
DEPTH_PRIORITY -是否根据请求的深度对其进行优先级排序。
HttpErrorMiddleware失败请求处理中间件
作用:
过滤出所有失败的HTTP Response,爬虫不需要消耗更多的资源,设置更为复杂的逻辑来处理这些异常Request。根据HTTP标准,返回值在200-300的为成功的Response.
如果想处理在这个范围之外的Response,可以通过Spider的handler_httpstatus_list属性或HTTPERROR_ALLOWED_CODES设置来指定Spider能处理的Response返回值。
当然,除非必要且目的明确,否则不推荐处理非200状态码的响应。
classscrapy.spidermiddlewares.httperror.HttpErrorMiddleware[源代码]¶
过滤掉不成功的(错误的)HTTP响应,这样spider就不必处理它们了,而这些(大部分时间)会增加开销,消耗更多的资源,并使spider逻辑更加复杂。
根据 HTTP standard ,成功的响应是状态代码在200-300范围内的响应。
如果仍要处理超出该范围的响应代码,可以使用 handle_httpstatus_list 蜘蛛属性或 HTTPERROR_ALLOWED_CODES 设置。
OffsiteMiddleware过滤请求中间件
classscrapy.spidermiddlewares.offsite.OffsiteMiddleware[源代码]¶
过滤掉对spider所覆盖域之外的URL的请求。
此中间件过滤掉其主机名不在爬行器中的每个请求 allowed_domains 属性。也允许列表中任何域的所有子域。例如,这条规则 www.example.org 还将允许 bob.www.example.org 但不是 www2.example.com 也不是 example.com 。
当您的spider返回一个不属于spider覆盖的域的请求时,这个中间件将记录一个与这个类似的调试消息:
DEBUG: Filtered offsite request to 'www.othersite.com': <GET http://www.othersite.com/some/page.html>
为了避免在日志中填充过多的噪声,它将只为每个过滤后的新域打印其中一条消息。例如,如果另一个请求 www.othersite.com 已筛选,将不打印日志消息。但如果有人要求 someothersite.com 过滤后,将打印一条消息(但仅针对过滤后的第一个请求)。
如果爬行器没有定义 allowed_domains 属性,或者该属性为空,则异地中间件将允许所有请求。
如果请求具有 dont_filter 属性集,则即使其域未列在允许的域中,非现场中间件也会允许该请求。
RefererMiddleware参考位置中间件
classscrapy.spidermiddlewares.referer.RefererMiddleware[源代码]¶
填充请求 Referer 头,基于生成它的响应的URL。
ReferermIddleware设置¶
REFERER_ENABLED¶
违约: True
是否启用引用中间件。
REFERRER_POLICY¶
违约: 'scrapy.spidermiddlewares.referer.DefaultReferrerPolicy'
Referrer Policy 填充请求“引用”头时应用。
UrlLengthMiddleware网址长度限制中间件
classscrapy.spidermiddlewares.urllength.UrlLengthMiddleware[源代码]¶
筛选出URL超过URL长度限制的请求
这个 UrlLengthMiddleware 可以通过以下设置进行配置(有关详细信息,请参阅设置文档):
URLLENGTH_LIMIT -允许已爬网URL的最大URL长度。
编写自定义下载器中间件
每个下载器中间件都是一个python类,它定义了下面定义的一个或多个方法。
主要入口点是 from_crawler 类方法,它接收 Crawler 实例。这个 Crawler 例如,对象允许您访问 settings .
classscrapy.downloadermiddlewares.DownloaderMiddleware¶
注解
任何下载器中间件方法也可能返回延迟。
process_request(request, spider)¶
对于通过下载中间件的每个请求调用此方法。
process_request() 应该选择哪一个:返回 None ,则返回一个 Response 对象,则返回一个 Request 对象,或引发 IgnoreRequest 。
如果它回来 None ,scrapy将继续处理此请求,执行所有其他中间软件,直到最后调用适当的下载器处理程序执行请求(及其下载的响应)。
如果它返回 Response 对象,Scrapy不用打电话了 any 其他 process_request() 或 process_exception() 方法或适当的下载函数;它将返回该响应。这个 process_response() 每次响应都会调用已安装中间件的方法。
如果它返回一个 Request 对象时,Scrapy将停止调用process_request方法,并重新调度返回的请求。一旦执行了新返回的请求,将对下载的响应调用适当的中间件链。
如果它引发了 IgnoreRequest 例外情况 process_exception() 将调用已安装的下载器中间件的方法。如果它们都不处理异常,则请求的errback函数 (Request.errback )。如果没有代码处理引发的异常,则忽略该异常,不记录该异常(与其他异常不同)。
参数
request (Request object) -- 正在处理的请求
spider (Spider object) -- 此请求所针对的蜘蛛
process_response(request, response, spider)¶
process_response() 应该是:返回一个 Response 对象,则返回一个 Request 对象或引发 IgnoreRequest 例外情况。
如果它返回 Response (可能是相同的给定响应,也可能是全新的响应),该响应将继续使用 process_response() 链中的下一个中间件。
如果它返回一个 Request 对象时,中间件链将暂停,返回的请求将重新计划为将来下载。这与从返回请求的行为相同 process_request() 。
如果它引发了 IgnoreRequest 异常,请求的errback函数 (Request.errback )。如果没有代码处理引发的异常,则忽略该异常,不记录该异常(与其他异常不同)。
参数
request (is a Request object) -- 发起响应的请求
response (Response object) -- 正在处理的响应
spider (Spider object) -- 此响应所针对的蜘蛛
process_exception(request, exception, spider)¶
Scrapy电话 process_exception() 当下载处理程序或 process_request() (从下载器中间件)引发异常(包括 IgnoreRequest 例外)
process_exception() 应返回:任一 None ,a Response 对象,或一个 Request 对象。
如果它回来 None ,Scrapy将继续处理此异常,执行任何其他 process_exception() 安装的中间件的方法,直到没有中间件,默认的异常处理开始。
如果它返回 Response 对象 process_response() 已安装中间件的方法链已启动,Scrapy不需要调用任何其他方法。 process_exception() 中间件的方法。
如果它返回一个 Request 对象,则返回的请求将被重新安排为将来下载。这会停止执行 process_exception() 中间件的方法与返回响应相同。
参数
request (is a Request object) -- 生成异常的请求
exception (an Exception object) -- 引发的异常
spider (Spider object) -- 此请求所针对的蜘蛛
from_crawler(cls, crawler)¶
如果存在,则调用该类方法从 Crawler . 它必须返回中间件的新实例。爬虫对象提供对所有零碎核心组件(如设置和信号)的访问;它是中间件访问它们并将其功能连接到零碎的一种方式。
参数
crawler (Crawler object) -- 使用此中间件的爬虫程序
下载器内置中间件
下方全部来自改资料https://www.osgeo.cn/scrapy/topics/downloader-middleware.html?highlight=%E4%B8%AD%E9%97%B4%E4%BB%B6
CookiesMiddleware
作用:
该中间件可以使用Cookie爬取网站数据。记录了向Web Server发送的Cookie,并在之后的Request请求中发送回去,就像操作浏览器一样。
很有用的一点是,每个住址爬虫可以保存多个cookies,只需要为Request.meta指定cookiejar值。
以下设置可用于配置cookie中间件:
COOKIES_ENABLED
COOKIES_DEBUG
HttpProxyMiddleware
作用:
此中间件可以通过在Request,meta中添加proxy属性值为该请求设置HTTP代理,默认获取代理的方式是通过以下环境变量来获取代理地址:
http_proxy
https_proxy
no_proxy
在settings.py中的设置:
HTTPPROXY_ENABLED:默认为False,表示是否激活HttpProxyMiddleware
HTTPPROXY_AUTH_ENCODING:代理有验证时的账户信息编码方式。
lassscrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware[源代码]¶
此中间件设置HTTP代理以用于请求,方法是设置 proxy 的元值 Request 对象。
就像Python标准库模块一样 urllib.request ,它遵循以下环境变量:
http_proxy
https_proxy
no_proxy
您也可以设置meta键 proxy per-request, to a value like http://some_proxy_server:port or http://username:password@some_proxy_server:port. Keep in mind this value will take precedence over http_proxy/https_proxy 环境变量,它也将忽略 no_proxy 环境变量。
配置中间件的实例
编写自定义中间件middlewares.py;这里分别添加一个Spider中间件一个Downloader中间件
from scrapy import signals
import scrapy
import random
class LianjiaSpiderMiddleware(object):
"""
利用Scrapy数据收集功能,记录相同小区的数量
"""
def __init__(self, stats):
self.stats = stats
@classmethod
def from_crawler(cls, crawler):
return cls(stats=crawler.stats)
def process_spider_output(self, response, result, spider):
"""
从item中获取小区名称,在数据收集其中记录相同小区数量
:param response:
:param result:
:param spider:
:return:
"""
for item in result:
if isinstance(item,scrapy.Item):
# 从result中的item获取小区名称
community_name = item['community_name']
# 在数据统计中为相同的小区增加数量值
self.stats.inc_value(community_name)
yield item
class LianjiaDownloaderMiddleware(object):
"""
为请求添加代理
"""
def __init__(self,proxy_list):
self.proxy_list = proxy_list
@classmethod
def from_crawler(cls, crawler):
# 从settings.py中获取代理列表
return cls(
proxy_list=crawler.settings.get('PROXY_LIST')
)
def process_request(self, request, spider):
# 从代理列表中随机选取一个添加至请求
proxy = random.choice(self.proxy_list)
request.meta['proxy'] = proxy
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
settings.py的配置
SPIDER_MIDDLEWARES = {
'lianjiahouse.middlewares.LianjiahouseSpiderMiddleware': 543,
}
# 这些中间件都是自己定义的啊
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
'lianjiahouse.middlewares.LianjiahouseDownloaderMiddleware': 543,
}
Scrapy基本配置
命令行选项优先级最高
执行命令时候,如果在项目内执行,默认就使用项目内配置,即settings.py中的配置信息,如果在项目外执行,就使用默认的命令行配置。在任何地方执行命令行命令,都可以使用命令行参数-s(或--set)来覆盖一个(或更多)配置信息,因为命令行的参数配置具有最高的优先级
# 例如
scrapy crawl myspider -s LOG_FILE=scrapy.log
每个爬虫内置配置
可参考官方文档内置设置参考
custom_settings可以为某些爬虫定制不同的配置,写在spider中,该变量为一个字典
class MySpider(scrapy.Spider):
name = 'myspider'
custom_settings = {
'SOME_SETTING': 'some value',
}
项目设置模块settings.py的讲解
通过scrapy startproject命令创建项目后,都会生成一个settings.py文件,该文件就是该项目的配置文件。
# Scrapy settings for test1 project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://docs.scrapy.org/en/latest/topics/settings.html
# https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# https://docs.scrapy.org/en/latest/topics/spider-middleware.html
# Scrapy项目名字
BOT_NAME = 'test1'
SPIDER_MODULES = ['test1.spiders']
NEWSPIDER_MODULE = 'test1.spiders'
# 注销的都是后面加的,就是项目需要他时,他在启用
# 使用Scrapy搜索spider的模块列表
# SPIDER_MODULES = ['segementfault.spiders']
# 使用爬虫创建命令genspider创建爬虫时生成的模块
# NEWSPIDER_MODULE = 'segementfault.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
# 默认的USER_AGENT,私用BOT_NAME配置生成,建议覆盖
#USER_AGENT = 'test1 (+http://www.yourdomain.com)'
# Obey robots.txt rules
# 如果启用,Scrapy则会遵守网站Rebots.txt协议,建议设置为False.
ROBOTSTXT_OBEY = False
# Configure maximum concurrent requests performed by Scrapy (default: 16)
# 配置Scrapy最大并发数,默认为32,一般需要增大设置
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
# 为同一个站点设置下载延迟
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
# 下载延迟的设置只会根据以下两个中的一个生效
# 对单个网站设置最大的请求并发数
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
# 对单个IP设置最大的请求并发数
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
# 禁用Cookie,默认True启用,建议为False
#COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
# 关闭Telent控制台,默认启用
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
# 默认的请求头,根据爬取网站覆盖
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
# 启用Spider爬虫中间件
#SPIDER_MIDDLEWARES = {
# 'test1.middlewares.Test1SpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# 启用Download下载器中间件
#DOWNLOADER_MIDDLEWARES = {
# 'test1.middlewares.Test1DownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
# 启用扩展
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# 配置管道信息
#ITEM_PIPELINES = {
# 'test1.pipelines.Test1Pipeline': 300,
#}
# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
# 启用配置AutoThrottle扩展,默认禁用,建议启用
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
# 初始化下载延迟
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
# 高延迟下最大的下载延迟
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
# Scrapy请求应该并行发送每个远程服务器的平均数量
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
# 启用调试模式,设计每一个响应状态数据
#AUTOTHROTTLE_DEBUG = False
# 启用和配置HTTP缓存
# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
# HTTP缓存过期时间
#HTTPCACHE_EXPIRATION_SECS = 0
# HTTP缓存目录
#HTTPCACHE_DIR = 'httpcache'
# HTTP缓存忽略的响应状态码
#HTTPCACHE_IGNORE_HTTP_CODES = []
# HTTP缓存存储目录
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
当我们编写完管道、中间件,使用扩展时,一定要在settings.py中启用,才能够正常使用。
默认的命令行配置
这两个有区别么,这都抄服了;就不是导入个模块
在项目中使用,默认的配置为项目配置
>scrapy settings --get BOT_NAME
scrapybot
在项目外使用命令行时,默认使用Scrapy全局配置
import scrapy
>scrapy settings --get BOT_NAME
scrapybot
默认全局配置(优先级最低)
Scrapy默认全局配置是所有配置信息的基础,每种配置都是在此基础上进行覆盖的。
日志
scrapy日志功能可查看https://www.osgeo.cn/scrapy/topics/logging.html?highlight=log_file#log-levels
Scrapy使用Python内置的日志系统记录事件日志,在使用日志功能之前还需进行一些配置。
LOG_FILE:指定日志文件,如果为None,就是用标准错误输出。
LOG_ENABLED:是否启用日志,为True时启用日志,为False时不启用
LOG_ENCODING:使用指定的编码方式输出日志,默认为UTF-8
LOG_LEVEL:日志记录的最低级别,可选的级别还有CRITICAL、ERROR、WARNING、INFO、DEBUG。默认为DEBUG,打印所有记录
LOG_FORMAT:日志输出格式,默认为'%(asctime)s[%(name)s]%(levelname)s:%(message)s'
LOG_DATEFORMAT:日志日期记录格式,默认格式为"%Y_%m%d%H:%M:%S"
LOG_STDOUT:默认为False,如果为True,那么表示进程所有的标准输出(及错误)将被重定向到log中。例如执行print 'hello',其将会在Scrapy log中显示。
数据收集
官网资料https://www.osgeo.cn/scrapy/topics/stats.html?highlight=%E6%94%B6%E9%9B%86#available-stats-collectors
scrapy数据收集有哪些作用,可以方便的统计一些特殊信息,包括一些指令数据的统计,比如特定的关键字、404页面等。Scrapy提供的这种收集数据机制叫做Stats Collection.
数据收集器对每个Spider保持一个状态表。当Spider启动时,该表自动打开,当Spider关闭时,该表自动关闭。
发送邮件
官网地址
有两种方法可以创建邮件发送其(Mail Sender)。可以通过标准构造器(Constructor)创建。
from scrapy.mail import MailSender
mailer= MailSender()
或者通过传递一个Scrapy设置对象,通过settings配置创建:
mailer = MailSender.from_settings(settings)
再使用send()方法来发送邮件(不包括附件)
mailer.send(to=["someone@example.com"],subject="Some subject",body="Some body",cc=["another@example.com"])
MailSender类介绍
略
在settings.py中对Mail进行设置
settings.py中的设置定义了MailSender构造器的默认值