golang-spider-從單任務版爬蟲到併發爬蟲01
學習總結:
- 設計的過程是簡單到複雜的演化過程
- 每一次的變化都應該是需求決定的
- 抽象的過程是清晰的概念和邏輯劃分的過程
單任務版爬蟲架構
- 第一步 將請求放入到engine的佇列中
- 第二步 engine重佇列取出請求交給fetcher去下載,fetcher將下載結果交給engine
- 第三步 engine將下載結果交給parser去解析,解析後結果交給engine進行下一步排程
package engine
import (
"hans/learn/spider/crawler/fetcher"
"log"
)
func Run(seeds ...Request){
var requests []Request
for _,r := range seeds {
requests = append(requests,r)
}
for len(requests) > 0 {
r := requests[0]
requests =requests[1:]
log.Printf("Fetching %s",r.Url)
body,err :=fetcher.Fetch(r.Url)
if err != nil {
log.Printf("Fetcher: error " +
"fetching url %s: %v",r.Url,err)
continue
}
parseResult := r.ParserFunc(body)
requests = append(requests,parseResult.Requests...)
for _,item := range parseResult.Items {
log.Printf("Got item %v",item)
}
}
}
改進一
上圖中的parser和fetcher可以合併成一步,叫做worker
func Run(seeds ...Request){
var requests []Request
for _,r := range seeds {
requests = append(requests,r)
}
for len(requests) > 0 {
r := requests[0]
requests =requests[1:]
log.Printf("Fetching %s",r.Url)
parseResult,err := worker(r)
if err != nil {
continue
}
requests = append(requests,parseResult.Requests...)
for _,item := range parseResult.Items {
log.Printf("Got item %v",item)
}
}
}
func worker(request Request) (ParseResult,error){
body,err := fetcher.Fetch(request.Url)
if err != nil {
log.Printf("Fetcher: error " +
"fetching url %s: %v",r.Url,err)
return ParseResult{},err
}
return request.ParserFunc(body),nil
}
改進二 併發版爬蟲
- 第一步,將request傳遞給engine
- 第二步,engine將request交給scheduler排程
- 第三步,scheduler將request放入channel,然後由worker進行解析
將解析結果再放入channel,scheduler從channel中獲取
parseResult繼續排程任務
engine做了哪些事情?
- 根據使用者配置WorkerCount,開啟多個goroutine實現併發
- 建立了供所有worker使用的channel
- 迴圈消費channel中的request,有就交給scheduler進行排程
scheduler做了哪些事情?如何履行排程的指責?
- 不停的把request放入channel中,供worker消費.......
engine.go
package engine
import "log"
type ConcurrentEngine struct {
Scheduler Scheduler
WorkerCount int
}
type Scheduler interface {
Submit(Request)
ConfigMasterWorkerChan(chan Request)
}
func (e *ConcurrentEngine) Run(seeds ...Request){
//scheduler建立多個worker去處理任務
in := make(chan Request)
out := make(chan ParseResult)
e.Scheduler.ConfigMasterWorkerChan(in)
for i :=0;i<e.WorkerCount;i++{
createWorker(in,out)
}
//將request扔給scheduler處理
for _,r := range seeds {
e.Scheduler.Submit(r)
}
//迴圈channel 將channel中的request交給scheduler去排程
countItem :=0
result := <- out
//迴圈處理channel
for {
//對item計數
for _,item := range result.Items{
log.Printf("Got item #%d %v \n",countItem,item)
countItem ++
}
//將request交給scheduler繼續排程
for _, request := range result.Requests {
log.Printf("Get Url %s",request.Url)
e.Scheduler.Submit(request)
}
}
}
func createWorker(in chan Request,out chan ParseResult){
//每一個worker都是一個goroutine,worker功能是fetcher和parser
go func(){
for {
//從in 這個channel中獲取request, fetcher處理後,將結果放回out 這個channel中
request := <- in
result,err :=worker(request)
if err != nil {
continue
}
out <- result
}
}()
}
scheduler.go
package scheduler
import "hans/learn/spider/crawler/engine"
type SimpleScheduler struct {
WorkerChan chan engine.Request
}
func (s *SimpleScheduler) Submit (r engine.Request) {
go func(){
s.WorkerChan <- r
}()
}
func (s *SimpleScheduler) ConfigMasterWorkerChan(c chan engine.Request){
s.WorkerChan = c
}
注: 程式碼示例地址
相關文章
- 【爬蟲】python爬蟲從入門到放棄爬蟲Python
- Python爬蟲教程-01-爬蟲介紹Python爬蟲
- 【Python學習】爬蟲爬蟲爬蟲爬蟲~Python爬蟲
- 爬蟲學習日記(六)完成第一個爬蟲任務爬蟲
- 01、部落格爬蟲爬蟲
- 實用爬蟲-01-檢測爬蟲的 IP爬蟲
- 【從零開始學爬蟲】對任務的操作爬蟲
- python爬蟲日記01Python爬蟲
- python併發爬蟲利器tomorrow(一)Python爬蟲
- 爬蟲:多程式爬蟲爬蟲
- python爬蟲---網頁爬蟲,圖片爬蟲,文章爬蟲,Python爬蟲爬取新聞網站新聞Python爬蟲網頁網站
- 不踩坑的Python爬蟲:Python爬蟲開發與專案實戰,從爬蟲入門 PythonPython爬蟲
- 通用爬蟲與聚焦爬蟲爬蟲
- 爬蟲--Scrapy簡易爬蟲爬蟲
- Socket爬蟲:Python版爬蟲Python
- python爬蟲系列版Python爬蟲
- Python《多執行緒併發爬蟲》Python執行緒爬蟲
- Python爬蟲基礎-01-帶有請求引數的爬蟲Python爬蟲
- python爬蟲實戰教程-Python爬蟲開發實戰教程(微課版)Python爬蟲
- 反爬蟲之字型反爬蟲爬蟲
- 爬蟲進階:反反爬蟲技巧爬蟲
- python爬蟲開發微課版pdf_Python爬蟲開發實戰教程(微課版)Python爬蟲
- 網路爬蟲---從千圖網爬取圖片到本地爬蟲
- 那些年,我爬過的北科(四)——爬蟲進階之極簡併行爬蟲框架開發爬蟲框架
- 爬蟲爬蟲
- Python 從入門到爬蟲極簡教程Python爬蟲
- 我爬取了爬蟲崗位薪資,分析後發現爬蟲真香爬蟲
- python爬蟲學習01--電子書爬取Python爬蟲
- 併發爬蟲_使用motor儲存資料爬蟲
- 網路爬蟲——爬蟲實戰(一)爬蟲
- 【爬蟲】爬蟲專案推薦 / 思路爬蟲
- 簡單的爬蟲程式爬蟲
- python簡單爬蟲(二)Python爬蟲
- 爬蟲開發技巧爬蟲
- 2個月精通Python爬蟲——3大爬蟲框架+6場實戰+反爬蟲技巧+分散式爬蟲Python爬蟲框架分散式
- Java爬蟲與Python爬蟲的區別?Java爬蟲Python
- 爬蟲與反爬蟲技術簡介爬蟲
- python就是爬蟲嗎-python就是爬蟲嗎Python爬蟲