亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

首頁 慕課教程 Scrapy 入門教程 Scrapy 入門教程 Scrapy 配置介紹及常見優化配置

Scrapy 配置介紹及常見優化配置

今天我們來看看 Scrapy 框架的相關配置項以及常見的一些優化配置。涉及的文件主要是 scrapy 項目的 settings.py 文件和 Scrapy 源碼目錄下的 scrapy/settings/default_settings.py 文件。這些內容會在我們每個 Scrapy 爬蟲項目中都會用到,特別是在爬取海量數據時需要特別注意的地方。

1. Scrapy 的 settings.py 配置

從前面的學習中我們知道,settings.py 是 Scrapy 使用 startproject 命令生成的,這里的配置會默認覆蓋 Scrapy 內置的配置項,這些默認的配置項都位于 Scrapy 的 scrapy/settings/default_settings.py 中:
圖片描述

Scrapy的默認配置文件

我們來看看 default_settings.py 中的一些默認配置項。

  • AJAXCRAWL_ENABLED:通用爬取經常會抓取大量的 index 頁面;AjaxCrawlMiddleware 能幫助我們正確地爬取,AJAXCRAWL_ENABLED 配置正是開啟該中間件的開關。由于有些性能問題,且對于特定爬蟲沒有什么意義,該中間默認關閉;

  • 自動限速擴展 (AutoThrottle):這類配置主要是以 Scrapy 爬蟲以及正在抓取網站的負載來自動優化爬取速度。它能自動調整 Scrapy 達到最佳的爬取速度,使用者無需自己設置下載延遲,只要設置好最大并發請求數即可。來看看有關該擴展的配置項:

    AUTOTHROTTLE_ENABLED = False      # 默認關閉
     AUTOTHROTTLE_DEBUG = False        # 關閉調試 
     AUTOTHROTTLE_MAX_DELAY = 60.0     # 最高下載延遲
     AUTOTHROTTLE_START_DELAY = 5.0    # 初始化下載延遲
     AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0  # Scrapy 同時請求目標網站的平均請求數
    

下面四個配置用于設置爬蟲自動關閉條件:

  • CLOSESPIDER_TIMEOUT:一個整數值,單位為秒。如果一個 spider 在指定的秒數后仍在運行, 它將以 closespider_timeout 的原因被自動關閉。 如果值設置為0 (或者沒有設置),spiders 不會因為超時而關閉;
  • CLOSESPIDER_ITEMCOUNT:一個整數值,指定條目的個數。如果 spider 爬取條目數超過了設置的值, 并且這些條目通過 item pipelines 傳遞,spider 將會以 closespider_itemcount 的原因被自動關閉;
  • CLOSESPIDER_PAGECOUNT:一個整數值,指定最大的抓取響應 (reponses) 數。 如果 spider 抓取數超過指定的值,則會以 closespider_pagecount 的原因自動關閉。 如果設置為0(或者未設置),spiders不會因為抓取的響應數而關閉;
  • CLOSESPIDER_ERRORCOUNT:一個整數值,指定spider可以接受的最大錯誤數。 如果spider生成多于該數目的錯誤,它將以 closespider_errorcount 的原因關閉。 如果設置為0(或者未設置),spiders不會因為發生錯誤過多而關閉;

以上四個參數在 default_settings.py 中設置的默認值都是0

并發相關,的設置會較大影響 Scrapy 爬蟲的性能。下面是默認的配置值,其中都已經進行了詳細的注釋說明:

# pipelines中并發處理items數
CONCURRENT_ITEMS = 100
# scrapy中并發下載請求數
CONCURRENT_REQUESTS = 16
# 對任何單個域執行的并發請求的最大數量
CONCURRENT_REQUESTS_PER_DOMAIN = 8
# 將對任何單個IP執行的并發請求的最大數量。如果非零
CONCURRENT_REQUESTS_PER_IP = 0

Cookie相關配置:

# 是否啟用cookiesmiddleware。如果關閉,cookies將不會發送給web server
COOKIES_ENABLED = True
# 如果啟用,Scrapy將記錄所有在request(cookie 請求頭)發送的cookies及response接收到的cookies(set-cookie接收頭),這也會間接影響性能,因此默認關閉。
COOKIES_DEBUG = False

請求深度相關配置,比如 DEPTH_LIMIT 設置請求允許的最大深度。如果為 0 ,則表示不受限;DEPTH_STATS_VERBOSE 參數控制是否收集詳細的深度統計信息;如果啟用此選項,則在統計信息中收集每個深度的請求數。DEPTH_PRIORITY 參數用于根據深度調整請求優先級。來看看他們的默認設置:

DEPTH_LIMIT = 0
DEPTH_STATS_VERBOSE = False
DEPTH_PRIORITY = 0

DNS 相關配置。DNSCACHE_ENABLED 用于控制是否啟用 DNS 緩存,DNSCACHE_SIZE參數設置緩存大小,DNS_TIMEOUT 處理 DNS 查詢超時時間;我們來具體看看 default_settings.py 中的默認配置:

DNSCACHE_ENABLED = True
DNSCACHE_SIZE = 10000
# 緩存解析器
DNS_RESOLVER = 'scrapy.resolver.CachingThreadedResolver'
DNS_TIMEOUT = 60

下載器相關。這部分的配置比較多,也是主要影響性能的地方。我們對一些關鍵的配置進行說明,具體如下:

  • DOWNLOAD_DELAY:下載器在從同一網站下載連續頁面之前應等待的時間,通過該配置可以限制爬蟲的爬取速度。此外,該設置也受RANDOMIZE_DOWNLOAD_DELAY 設置(默認情況下啟用)的影響。
  • DOWNLOAD_TIMEOUT:下載超時時間;
  • DOWNLOAD_MAXSIZE:下載器將下載的最大響應大?。?/li>
  • DOWNLOAD_HANDLERS_BASE:處理不同類型下載的下載器;
  • DOWNLOAD_FAIL_ON_DATALOSS:數據丟失后是否繼續下載;
  • DOWNLOADER_MIDDLEWARESDOWNLOADER_MIDDLEWARES_BASE:分別表示自定義的下載中間件類和默認的下載中間件類;
  • DOWNLOADER_STATS:是否啟用下載器統計信息收集。

來看看 default_settings.py 中的默認配置,具體如下:

DOWNLOAD_DELAY = 0

DOWNLOAD_HANDLERS = {}
DOWNLOAD_HANDLERS_BASE = {
    'data': 'scrapy.core.downloader.handlers.datauri.DataURIDownloadHandler',
    'file': 'scrapy.core.downloader.handlers.file.FileDownloadHandler',
    'http': 'scrapy.core.downloader.handlers.http.HTTPDownloadHandler',
    'https': 'scrapy.core.downloader.handlers.http.HTTPDownloadHandler',
    's3': 'scrapy.core.downloader.handlers.s3.S3DownloadHandler',
    'ftp': 'scrapy.core.downloader.handlers.ftp.FTPDownloadHandler',
}

DOWNLOAD_TIMEOUT = 180      # 3mins

DOWNLOAD_MAXSIZE = 1024 * 1024 * 1024   # 1024m
DOWNLOAD_WARNSIZE = 32 * 1024 * 1024    # 32m

DOWNLOAD_FAIL_ON_DATALOSS = True

DOWNLOADER = 'scrapy.core.downloader.Downloader'

DOWNLOADER_HTTPCLIENTFACTORY = 'scrapy.core.downloader.webclient.ScrapyHTTPClientFactory'
DOWNLOADER_CLIENTCONTEXTFACTORY = 'scrapy.core.downloader.contextfactory.ScrapyClientContextFactory'
DOWNLOADER_CLIENT_TLS_CIPHERS = 'DEFAULT'
# Use highest TLS/SSL protocol version supported by the platform, also allowing negotiation:
DOWNLOADER_CLIENT_TLS_METHOD = 'TLS'
DOWNLOADER_CLIENT_TLS_VERBOSE_LOGGING = False

DOWNLOADER_MIDDLEWARES = {}

DOWNLOADER_MIDDLEWARES_BASE = {
    # Engine side
    'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware': 100,
    'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware': 300,
    'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware': 350,
    'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware': 400,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 500,
    'scrapy.downloadermiddlewares.retry.RetryMiddleware': 550,
    'scrapy.downloadermiddlewares.ajaxcrawl.AjaxCrawlMiddleware': 560,
    'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware': 580,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 590,
    'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': 600,
    'scrapy.downloadermiddlewares.cookies.CookiesMiddleware': 700,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,
    'scrapy.downloadermiddlewares.stats.DownloaderStats': 850,
    'scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware': 900,
    # Downloader side
}

DOWNLOADER_STATS = True

DUPEFILTER_CLASS:指定去重類;

DUPEFILTER_CLASS = 'scrapy.dupefilters.RFPDupeFilter'

自定義擴展和內置擴展配置:

EXTENSIONS = {}

EXTENSIONS_BASE = {
    'scrapy.extensions.corestats.CoreStats': 0,
    'scrapy.extensions.telnet.TelnetConsole': 0,
    'scrapy.extensions.memusage.MemoryUsage': 0,
    'scrapy.extensions.memdebug.MemoryDebugger': 0,
    'scrapy.extensions.closespider.CloseSpider': 0,
    'scrapy.extensions.feedexport.FeedExporter': 0,
    'scrapy.extensions.logstats.LogStats': 0,
    'scrapy.extensions.spiderstate.SpiderState': 0,
    'scrapy.extensions.throttle.AutoThrottle': 0,
}

文件存儲相關:

FILES_STORE_S3_ACL = 'private'
FILES_STORE_GCS_ACL = ''

FTP 服務配置, Scrapy 框架內置 FTP 下載程序。我們可以指定 FTP 的相關參數:

FTP_USER = 'anonymous'
FTP_PASSWORD = 'guest'
FTP_PASSIVE_MODE = True

HTTP 緩存相關配置。Scrapy 的 HttpCacheMiddleware 組件(默認情況下沒有啟用)提供了一個底層的對HTTP請求和響應的緩存。如果啟用的話(把HTTPCACHE_ENABLED設置為True),它會緩存每個請求和對應的響應。來看看和其相關的配置和含義:

# 是否啟用http緩存
HTTPCACHE_ENABLED = False
# 緩存數據目錄
HTTPCACHE_DIR = 'httpcache'
HTTPCACHE_IGNORE_MISSING = False
# 緩存存儲的插件
HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# 緩存過期時間
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_ALWAYS_STORE = False
# 緩存忽略的Http狀態碼
HTTPCACHE_IGNORE_HTTP_CODES = []
HTTPCACHE_IGNORE_SCHEMES = ['file']
HTTPCACHE_IGNORE_RESPONSE_CACHE_CONTROLS = []
HTTPCACHE_DBM_MODULE = 'dbm'
# 設置緩存策略,DummyPolicy是所有請求均緩存,下次在請求直接訪問原來的緩存即可
HTTPCACHE_POLICY = 'scrapy.extensions.httpcache.DummyPolicy'
# 是否啟用緩存數據壓縮
HTTPCACHE_GZIP = False

Item 和 Item pipelines相關配置:

# ITEM處理器
ITEM_PROCESSOR = 'scrapy.pipelines.ItemPipelineManager'
# 自定義的 item pipelines
ITEM_PIPELINES = {}
ITEM_PIPELINES_BASE = {}

日志相關的配置:

# 啟動日志功能
LOG_ENABLED = True
# 日志編碼
LOG_ENCODING = 'utf-8'
# 日志格式器
LOG_FORMATTER = 'scrapy.logformatter.LogFormatter'
# 日志格式
LOG_FORMAT = '%(asctime)s [%(name)s] %(levelname)s: %(message)s'
# 日志時間格式
LOG_DATEFORMAT = '%Y-%m-%d %H:%M:%S'
LOG_STDOUT = False
# 日志級別
LOG_LEVEL = 'DEBUG'
# 指定日志輸出文件
LOG_FILE = None
LOG_SHORT_NAMES = False

郵件配置:在 Scrapy 中提供了郵件功能,該功能使用十分簡便且采用了 Twisted 非阻塞模式,避免了對爬蟲的影響。我們只需要在 Scrapy 中進行簡單的設置,就能通過 API 發送郵件。郵件的默認配置項如下:

MAIL_HOST = 'localhost'
MAIL_PORT = 25
MAIL_FROM = 'scrapy@localhost'
MAIL_PASS = None
MAIL_USER = None

我們現在可以簡單的使用下 Scrapy 給我們提供的郵件類,來利用它給我們自己發送一封郵件。首先需要找下自己的 qq 郵箱或者其他郵箱,開啟 POP3/SMTP服務,然后我們可以得到一個授權碼。這個就是我們登陸這個郵箱服務的密碼。然后我們配置 settings.py 中的相應項:

MAIL_HOST = 'smtp.qq.com'
MAIL_PORT = 25
MAIL_FROM = '[email protected]'
MAIL_PASS = '你的授權碼'
MAIL_USER = '[email protected]'

接下來我們在 scrapy shell 中來調用相應的郵件接口,發送郵件:

(scrapy-test) [root@server china_pub]# scrapy shell --nolog
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x7f1c3d4e9100>
[s]   item       {}
[s]   settings   <scrapy.settings.Settings object at 0x7f1c3d4e6dc0>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects 
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
>>> from scrapy.mail import MailSender
>>> mailer = MailSender().from_settings(settings)
>>> mailer.send(to=["[email protected]"], subject="這是一個測試", body="來自百度云主機發送的一封郵件", cc=["[email protected]"])
<Deferred at 0x7f1c3c4d1c40>

圖片描述

調用 Scrapy 的郵件接口發送郵件

內存相關參數:

MEMDEBUG_ENABLED = False        # enable memory debugging
MEMDEBUG_NOTIFY = []            # send memory debugging report by mail at engine shutdown

MEMUSAGE_CHECK_INTERVAL_SECONDS = 60.0
# 是否啟用內存使用擴展
MEMUSAGE_ENABLED = True
# 在關閉Scrapy之前允許的最大內存量,為0則不檢查
MEMUSAGE_LIMIT_MB = 0
# 要達到內存限制時通知的電子郵件列表
MEMUSAGE_NOTIFY_MAIL = []
# 在發送警告電子郵件通知之前,要允許的最大內存量(以兆字節為單位)。如果為零,則不會產生警告
MEMUSAGE_WARNING_MB = 0

調度器相關配置:

# 調度器類
SCHEDULER = 'scrapy.core.scheduler.Scheduler'
# 指定調度器的三種隊列類
SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleLifoDiskQueue'
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeues.LifoMemoryQueue'
SCHEDULER_PRIORITY_QUEUE = 'scrapy.pqueues.ScrapyPriorityQueue'
# 正在處理響應數據的軟限制(以字節為單位),如果所有正在處理的響應的大小總和高于此值,Scrapy不會處理新的請求
SCRAPER_SLOT_MAX_ACTIVE_SIZE = 5000000

spider 中間件相關配置,有我們熟悉的 SPIDER_MIDDLEWARESSPIDER_MIDDLEWARES_BASE,表示自定義的 Spider 中間件和 Scrapy 內置的 Spider 中間件;

SPIDER_MIDDLEWARES = {}

SPIDER_MIDDLEWARES_BASE = {
    # Engine side
    'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': 50,
    'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': 500,
    'scrapy.spidermiddlewares.referer.RefererMiddleware': 700,
    'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware': 800,
    'scrapy.spidermiddlewares.depth.DepthMiddleware': 900,
    # Spider side
}

指定模板文件目錄,這個在使用 scrapy startproject 項目名 命令創建項目時,對應的模板文件所在的目錄:

TEMPLATES_DIR = abspath(join(dirname(__file__), '..', 'templates'))

USER_AGENT:設置請求頭的 User-Agent 參數,用來模擬瀏覽器。我們通常都會添加一個瀏覽器的 User-Agent 值,防止爬蟲直接被屏蔽;

Scrapy 的大體配置就是這些,還有一些沒有介紹到的參數,課后可以仔細查看官方文檔進行了解。

2. 常見的優化配置參數

首先 scrapy 框架有一個命令 (bench) 來幫助我們測試本地環境的效率,它會在本地創建一個 HTTP 服務器,并以最大可能的速度進行爬取,這個模擬的 Spider 只會做跟進連接操作,而不做其他處理。我們來實際看看這個命令的執行效果:

(scrapy-test) [root@server qidian_yuepiao]# scrapy bench
# ...
2020-07-25 23:35:07 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 127918,
 'downloader/request_count': 278,
 'downloader/request_method_count/GET': 278,
 'downloader/response_bytes': 666962,
 'downloader/response_count': 278,
 'downloader/response_status_count/200': 278,
 'elapsed_time_seconds': 11.300798,
 'finish_reason': 'closespider_timeout',
 'finish_time': datetime.datetime(2020, 7, 25, 15, 35, 7, 370135),
 'log_count/INFO': 21,
 'memusage/max': 48553984,
 'memusage/startup': 48553984,
 'request_depth_max': 12,
 'response_received_count': 278,
 'robotstxt/request_count': 1,
 'robotstxt/response_count': 1,
 'robotstxt/response_status_count/200': 1,
 'scheduler/dequeued': 277,
 'scheduler/dequeued/memory': 277,
 'scheduler/enqueued': 5540,
 'scheduler/enqueued/memory': 5540,
 'start_time': datetime.datetime(2020, 7, 25, 15, 34, 56, 69337)}
2020-07-25 23:35:07 [scrapy.core.engine] INFO: Spider closed (closespider_timeout)

在上面的執行日志中,我們可以很清楚的看到該命令會搜索 settings.py 中的配置并打印項目的基本信息以及啟用的擴展、下載中間件、Spider 中間件以及相應的 item pipelines。接下來是做的一些本地環境測試,測試顯示的是每分鐘平均能抓取1440個頁面,當然實際的爬蟲程序中需要有較多的處理,比如抽取頁面數據、過濾、去重以及保存到數據庫中,這些都是會消耗一定時間的。

現在來介紹一下 settings.py 中比較常見的一個優化配置:

  • 并發控制settings.py 中的 CONCURRENT_REQUESTS 參數用來確定請求的并發數,默認給的是16。而這個參數往往不適用于本地環境,我們需要進行調整。調整的方法是一開始設置一個比較大的值,比如100,然后進行測試,得到 Scrapy 的并發請求數與 CPU 使用率之間的關系,我們選擇大概使得 CPU 使用率在 80%~90% 對應的并發數,這樣能使得 Scrapy 爬蟲充分利用 CPU 進行網頁爬??;

  • 關閉 Cookie :這也是一個常見的優化策略。對于一些網站的請求,比如起點網、京東商城等, 不用登錄都可以任意訪問數據的,沒有必要使用 Cookie,使用 Cookie 而會增加 Scrapy 爬蟲的工作量。直接設置 COOKIES_ENABLED = False 即可關閉 Cookie;

  • 設置 Log 級別:將默認的 DEBUG 級別調整至 INFO 級別,減少不必要的日志打?。?/p>

  • 關閉重試:默認情況下 Scrapy 會對失敗的請求進行重試,這種操作會減慢數據的爬取效率,因為對于海量的請求而言,丟失的數個甚至數百個請求都無關緊要;反而不必要的嘗試會影響爬蟲爬取效率;生產環境的做法最好是直接關閉,即 RETRY_ENABLED = False;

  • 減少下載超時時間:對于響應很慢的網站,在超時時間結束前,Scrapy 會持續等到響應返回,這樣容易造成資源浪費。因此一個常見的優化策略是,減少超時時間,盡量讓響應慢的請求釋放資源。相應的參數設置示例如下:

    DOWNLOAD_TIMEOUT = 3
    
  • 關閉重定向:除非對重定向內容感興趣,否則可以考慮關閉重定向。關閉操作 REDIRECT_ENABLED = False;

  • 自動調整爬蟲負載:我們啟用這個可以自動調節服務器負載的擴展程序,設置相關的參數,可以一定程度上優化爬蟲的性能;

    AUTOTHROTTLE_ENABLED = False # 默認不啟用,可以設置為True并調整下面相關參數
    AUTOTHROTTLE_DEBUG = False
    AUTOTHROTTLE_MAX_DELAY = 60.0
    AUTOTHROTTLE_START_DELAY = 5.0
    AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
    

3. 小結

本小節中我們首先介紹了 settings.py 中的相關配置參數,先了解這些基礎的配置的含義,然后才知道如何選擇較合適的參數,這些對于 Scrapy 爬蟲性能有著較大的影響。當然這些性能變化可能在我們編寫的實驗性爬蟲中無法體現,但是對于真正的爬蟲公司而言,這些參數的調優對他們而言至關重要,甚至能決定公司的核心競爭力。為此,我們需要積極儲備相關知識,說不定會在未來有一天用的上。