Scrapy常用配置
2022年6月30日大约 4 分钟
本文基于scrapy 2.6版本说明
前言
经历了半个月的调参,整理了一些Scrapy中常用的配置和实践方式(都是血和泪的教训TAT)
配置说明
settings.py 常用配置
建议将全局配置放入该位置, 例如数据库连接, 第三方秘钥, 邮件配置/webhook等信息, 与 Spider 相关的配置不建议放在该文件中
# 是否遵循robots.txt规则(建议关闭)
ROBOTSTXT_OBEY = False
# 注意: 网站实际最大并发数为min(CONCURRENT_REQUESTS, CONCURRENT_REQUESTS_PER_DOMAIN, CONCURRENT_REQUESTS_PER_IP)
# 否则可能达不到自己预期的并发数
# 最大并发请求数, 默认: 16
CONCURRENT_REQUESTS = 16
# 每个网站的最大并发请求数
CONCURRENT_REQUESTS_PER_DOMAIN = 16
# 每个IP的最大并发请求数
CONCURRENT_REQUESTS_PER_IP = 16
# 下载延迟, 防止下载速度过快对网站服务器造成影响, 这会产生一个随机值, 值域为 0.5 * DOWNLOAD_DELAY ~ 1.5 * DOWNLOAD_DELAY
DOWNLOAD_DELAY = 0
# 禁用去重功能, 视具体场景而定, 若为长运行爬虫且URL多样性递增, 建议配置该项防止scrapy去重文件防止requests.seen持续增加导致磁盘占用过大(血与泪的教训, 之前没配置这个20个spider跑了3天打了几十个G)
# DUPEFILTER_CLASS = 'scrapy.dupefilters.BaseDupeFilter'
# url长度限制, 强烈建议调大(也是血泪的教训), 或者能够把控所以url长度不超过2083字符可忽略该配置
URLLENGTH_LIMIT = 2083
# jobdir 可用于暂停spider保留未运行的url, 适合任务需要暂停或中断接着上一次完成位置接着运行的场景
# JOBDIR = ''
# 是否开启重试, 默认: True
RETRY_ENABLED = True
# 是否开启Cookie, 默认: True
COOKIES_ENABLED = True
# 是否开启重定向, 默认: True
REDIRECT_ENABLED = True
# 固定UA, 一般用不上, 直接使用scrapy拓展的随机UA或自己写一个随机UA即可, 默认: None
USER_AGENT = None
# 全局日志级别, 值域: CRITICAL, ERROR, WARNING, INFO, DEBUG
LOG_LEVEL = 'DEBUG'
# 日志格式化样式, 实际使用中配置json字符串结构方便采集
LOG_FORMAT = '%(asctime)s [%(name)s] %(levelname)s: %(message)s'
# 日志存储文件路径
LOG_FILE = None
# logstats统计时间间隔, 默认60s, 可根据需求调整或关闭(None)
LOGSTATS_INTERVAL = 60.0
# 解决下载编码问题
FEED_EXPORT_ENCODING = 'utf-8'
# 全局拓展配置
EXTENSIONS = {
}
# 全局ITEM 管道配置
ITEM_PIPELINES = {
}
# 全局默认请求头配置, 不建议配置, 建议在spider中配置或处理层配置
DEFAULT_REQUEST_HEADERS = {
}
# 全局爬虫中间件配置
SPIDER_MIDDLEWARES = {
}
# 其他一些业务全局应用配置可定义在此, 通过 settings.get() 获取配置
spiders/
所有 Spider 继承 BaseSpider , 重写构造方法即可从配置中初始化 Spider
建议将与单个 Spider 相关的配置放入 Spider 的 custom_settings 中,例如最大并发数, IP最大并发数, 是否开启 cookie 以及额外配置等
import scrapy
class BaseSpider(scrapy.Spider):
def __init__(self, settings):
pass
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
# 创建spider时传入settings参数
spider = cls(crawler.settings, *args, **kwargs)
spider._set_crawler(crawler)
return spider
class DemoSpider(BaseSpider):
name = 'DemoSpider'
# 允许处理的http状态码, 默认parse只处理200~300的状态码
handle_httpstatus_list = []
# 同settings.py配置一样, 该配置优先级高于settings.py, 通过self.settings.get()获取
custom_settings = {
# 是否开启重试
'RETRY_ENABLED': False,
}
def __init__(self, settings):
super().__init__(settings)
# 通过配置初始化爬虫逻辑
middlewares.py
所有 SpiderMiddleware 继承 BaseSpiderMiddleware, DownloaderMiddleware 继承 BaseDownloaderMiddleware, 重写构造方法即可从配置中初始化 Middlewares
import signals
from utils import get_single_name
class BaseSpiderMiddleware:
"""
基础爬虫中间件, 含settings参数的构造方法
"""
def __init__(self, settings=None):
self.settings = settings
@classmethod
def from_crawler(cls, crawler):
s = cls(crawler.settings)
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(self, response, spider):
return None
def process_spider_output(self, response, result, spider):
for i in result:
yield i
def process_spider_exception(self, response, exception, spider):
spider.logger.warn('SpiderMiddleware %s, Spider %s, process exception: %s' % (get_single_name(self), spider.name, exception))
def process_start_requests(self, start_requests, spider):
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('SpiderMiddleware %s, Spider opened: %s' % (get_single_name(self), spider.name))
class BaseDownloaderMiddleware:
"""
基础下载中间件, 含settings参数的构造方法
"""
def __init__(self, settings=None):
self.settings = settings
@classmethod
def from_crawler(cls, crawler):
s = cls(crawler.settings)
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
return None
def process_response(self, request, response, spider):
return response
def process_exception(self, request, exception, spider):
spider.logger.warn('DownloadMiddleware %s, Spider %s, process exception: %s' % (get_single_name(self), spider.name, exception))
def spider_opened(self, spider):
spider.logger.info('DownloadMiddleware: %s, Spider opened: %s' % (get_single_name(self), spider.name))
pipelines.py
所有 Pipeline 继承 BasePipeline 重写构造方法即可从配置中初始化 Pipeline
通过配置加载 Pipeline 的初始化更易于管理与维护
import signals
from utils import get_single_name
class BasePipeline:
"""
基础管道, 含settings参数的构造方法
"""
def __init__(self, settings=None):
self.settings = settings
@classmethod
def from_crawler(cls, crawler):
s = cls(crawler.settings)
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_item(self, item, spider):
return item
def spider_opened(self, spider):
spider.logger.info('Pipeline: %s, Spider opened: %s' % (get_single_name(self), spider.name))
utils/
存放一些额外处理工具
__init__.py
def get_single_name(tp):
# 获取唯一名称, 可自行实现
pass
原创声明
平台文章均为原创文章,未经许可,禁止转载。
如需转载,请联系作者获取授权,并注明来源及原文链接。