Go語言網路爬蟲條目處理管道

2020-07-16 10:04:51
條目處理管道的介面擁有額外的 ItemProcessors、Send、FailFast 和 SetFailFast 方法,因此其實現型別 myPipeline 的基本結構是這樣的:
//條目處理管道的實現型別
type myPipeline struct {
    //元件基礎範例
    stub.ModuleInternal
    //條目處理器的列表
    itemProcessors []module.ProcessItem
    //處理是否需要快速失敗
    failFast bool
}
程式碼包 gopcp.v2/chapter6/webcrawler/module/local/pipeline 是存放該型別的位置,其中 New 函數與 analyzer 包中的 New 函數在引數宣告列表和引數檢查方式方面都很類似,這裡就省略不講了。相關程式碼包的程式碼大家可以在網路硬碟(連結:https://pan.baidu.com/s/1yzWHnK1t2jLDIcTPFMLPCA 提取碼:slm5)中下載。

除此之外,分析器中有 HTTP 響應解析函數的列表,而條目處理管道中有條目處理常式(以下簡稱處理常式)的列表。因此,後者的 Send 方法與前者的 Analyze 方法在實現流程方面也大體一致。只不過由於條目處理管道存在對快速失敗的設定,所以在流程細節上它們仍有不同。

另外,還要注意,條目處理管道需要讓條目依次經過那幾個處理常式的加工。也就是說,第一個處理常式的處理結果要作為第二個處理常式的引數,第二個處理常式的處理結果要作為第三個處理常式的引數,以此類推。這是由條目處理管道的設計決定的,也是“管道” 一詞要表達的含義。

相比之下,分析器中的解析函數對 HTTP 響應的解析是相互獨立的。下面是 Send 方法的程式碼片段,體現了上述不同:
func (pipeline *myPipeline) Send(item.module.Item) []error {
    //省略部分程式碼
    var errs []error
    //省略部分程式碼
    var currentItem = item
    for _, processor := range pipeline.itemProcessors {
        processedItem, err := processor(currentItem)
        if err != nil {
            errs = append(errs, err)
            if pipeline.failFast {
                break
            }
        }
        if processedItem != nil {
            currentltem = processedItem
        }
    }
    //省略部分程式碼
    return errs
}
ItemProcessors、FailFast和SetFailFast方法的實現都非常簡單,在此略過。

至此,我已經講解了元件相關介面的絕大部分實現,同時闡述了一些我在 Go語言程式編寫和軟體設計方面的經驗,也展示了一些編碼技巧。