Scrapy原始碼閱讀 Spider引數傳遞

2021-10-23 12:50:10 字數 2869 閱讀 1881

官方文件spider引數中提到,可以使用scrapy crawl命令的-a選項向spider傳遞引數:

scrapy crawl myspider -a arg1=value1 -a arg2=value2

這些引數會被傳遞到自定義的myspider類的建構函式,並且超類spider的建構函式會將其拷貝到屬性中:

import scrapy

class

myspider

(scrapy.spider)

: name =

'myspider'

def__init__

(self,

*args,

**kwargs)

:# kwargs['arg1'] == 'value1'

# kwargs['arg2'] == 'value2'

super()

.__init__(

*args,

**kwargs)

# self.arg1 == 'value1'

# self.arg2 == 'value2'

那麼這些命令列引數是如何被解析,並最終設定為spider的屬性的?下面通過原始碼分析這一過程。

從scrapy的命令列模組scrapy.cmdline入手,通過命令列輸入的命令由該模組中的execute()函式執行:

這裡有兩個關鍵的物件:parser是python內建模組optparse中的optionparser類的物件,用於解析命令列引數;cmd是命令類的物件(crawl命令對應scrapy.commands.crawl.command類)

該函式的幾個關鍵步驟:

例如,待解析的命令列引數為-a arg1=value1 -a arg2=value2,解析結果為opts,則opts.spargs是長度為2的列表['arg1=value1', 'arg2=value2']

(2)處理解析結果

baserunspidercommandprocess_options()方法解析了opts.spargs並將其轉換為字典

因此['arg1=value1', 'arg2=value2']將變為

至此,解析命令列引數已完成,下面分析cmd.run()如何使用這些解析結果。

檢視scrapy.commands.crawl.commandrun()方法的**:

引數opts為之前的解析結果,run()方法以關鍵字引數的形式將opts.spargs傳入scrapy.crawler.crawlerprocess類的crawl()方法,該方法繼承自crawlerrunner.crawl(),繼續跟蹤該方法的呼叫過程

經過crawlerrunner.crawl()->crawlerrunner._crawl()->crawler.crawl()->crawler()._create_spider()幾次呼叫後,kwargs(即之前的opts.spargs)最終被傳遞到spider.from_crawler()方法,上圖中最後一行的spidercls就是自定義的myspider

檢視spider.from_crawler()方法的**:

可以看到,kwargs被傳入cls(即自定義的myspider類)的建構函式,如果myspider類沒有定義建構函式則繼承spider類的建構函式

檢視spider類的**,發現其建構函式中的下面這行**將kwargs中的鍵值對轉換為自身的屬性:

至此spider引數的傳遞過程已經分析清楚。

Scrapy原始碼閱讀 response處理過程

以官方教程quotesspider為例,結合原始碼分析一下scrapy中response的處理過程。下面是待爬取的網頁,紅框中的是目標html標籤 quote文字內容 如果output是request物件,則將其交給引擎準備繼續爬取,開啟executionengine類的crawl方法可以看到引擎直...

《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具

檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...

原始碼閱讀 Glide原始碼閱讀之with方法(一)

前言 本篇基於4.8.0版本 原始碼閱讀 glide原始碼閱讀之with方法 一 原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 大多數情況下,我們使用glide 就一句 但是這一句 裡面蘊含著成噸的 with方法有以下幾個過載方法 publi...