強大高效而精簡易用的Golang爬蟲框架Colly,能否取代 Scrapy?

      網友投稿 2844 2025-04-01

      前言


      任何剛接觸爬蟲編程的朋友可能都熟悉或者或多或少了解過基于 Python 異步框架 Twisted 的爬蟲框架 Scrapy。Scrapy 發展了將近 7 年,是爬蟲框架中的開山鼻祖,自然而然成為最受歡迎的也是應用最廣的爬蟲框架。對于 Scrapy 來說,其天然的優勢是支持并發,而且集成了 HTTP 請求、下載、解析、調度等爬蟲程序中常見的功能模塊,讓爬蟲工程師只專注于頁面解析和制定抓取規則,在當時極大的簡化了爬蟲開發流程,提高了開發效率。

      但是,Scrapy 并不是完美的,它仍然有不少缺點。其中,它的模版定制化成為了制約 Scrapy 爬蟲項目的雙刃劍:一方面,Scrapy 抽象出了各種必要的模塊,包括爬蟲(Spider)、抓取結果(Item)、中間件(Middleware)、管道(Pipeline)、設置(Setting)等,讓用戶可以直接上手按照一定規則編寫自己想要開發的爬蟲程序;另一方面,這些高度抽象的模塊讓整個爬蟲項目顯得比較臃腫,每個爬蟲項目都需要按照相應的模版生成好幾個文件,導致配置、爬蟲等管理起來相對比較混亂。而且,Scrapy 在一些特殊場景例如分布式抓取時顯得心有余而力不足,因此很多高級爬蟲工程師甚至需要更改 Scrapy 源碼來滿足業務要求。

      下圖是 Colly 和 Scrapy 在 Github 的 Star 數對比。可以看到 Colly 發展較晚,star 數不到 Scrapy 的三分之一,但還在高速增長當中。本文將著重介紹這個年輕而強大的爬蟲框架: Colly。

      靜態語言 Golang

      Colly 是基于靜態語言 Golang 開發的。眾所周知,Golang 也是一個比較年輕的語言,僅有 13 年歷史(相較而言,Python 有將近 30 年歷史)。Golang 天然支持并發(Concurrency),要起一個協程(Coroutine),只需要在調用函數前加一個 go 關鍵詞即可,非常簡單。當然,Golang 還有其他很棒的特性,例如通道(chan)。不過對于爬蟲來說支持并發是非常重要的,因為一個高效的爬蟲需要盡可能多的占用網絡帶寬資源,Golang 的并發特性給編寫爬蟲框架來說帶來了優勢。反觀 Python,如果要實現并發的話需要做很多工作,包括利用 asyncio 庫和從 JavaScript ES7 借鑒過來的 async/await 語法,并不是很直觀。

      下面是 Golang 的異步語法例子。

      func?run()?{

      fmt.Printf("hello?world")

      }

      func?main()?{

      go?run()

      }

      下面是 Python 的異步語法例子。

      import?asyncio

      async?def?main():

      print('Hello?...')

      await?asyncio.sleep(1)

      print('...?World!')

      #?Python?3.7+

      asyncio.run(main())

      Golang 作為靜態語言還有另一個非常重要的優勢,也就是其代碼的可預測性(Predictability)。靜態語言要求變量、參數以及函數返回結果都指定相應的類型,并且在編譯的時候會檢查類型的正確性,保證代碼的可靠性。用靜態語言編寫的一個好處,就是可以讓自己避免很多因為類型錯誤導致的 bug。因此,對于可靠性和健壯性要求較高的大型項目來說,用靜態語言編寫會是比較合理的選擇。編寫 Golang 程序的時候,IDE 會根據類型或變量自動補全潛在的代碼,是不是很香。相反,以 Python 為代表的動態語言,就沒那么嚴格了。雖然 Python 是強類型語言,但它并不存在預編譯的過程,因此無法在編譯時(Compile)檢測出類型錯誤。很多時候如果類型傳入不對,都會在運行時(Runtime)導致錯誤。網上流傳的 “動態一時爽,重構火葬場”,說的也是這個道理。雖然動態語言(例如 Python)給抓取結果賦予了一定的靈活性,但在我看來,大型爬蟲項目用靜態語言(例如 Golang)會是個更合理的選擇。

      Colly

      之前也介紹了,Colly 是一個由 Golang 編寫的爬蟲框架。Colly 其實是 Collector 或 Collecting 的昵稱。它精簡易用而強大高效,正在逐漸成為 Scrapy 以外的爬蟲框架選擇。

      咱們下面用一個例子來看一下它是如何做到的。(本文不是 Colly 的參考文檔,僅希望通過一些例子來介紹 Colly 的優勢和特性,要看所有 API 請參考 Colly 官網文檔)

      在任意目錄創建 baidu_spider.go 文件,并輸入下列代碼。

      package?main

      import?(

      "fmt"

      "github.com/crawlab-team/crawlab-go-sdk/entity"

      "github.com/gocolly/colly/v2"

      )

      func?main()?{

      //?生成?colly?采集器

      c?:=?colly.NewCollector(

      colly.AllowedDomains("www.baidu.com"),

      colly.Async(true),

      colly.UserAgent("Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_14_6)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/84.0.4147.135?Safari/537.36"),

      )

      //?抓取結果數據鉤子函數

      c.OnHTML(".result.c-container",?func(e?*colly.HTMLElement)?{

      //?抓取結果實例

      item?:=?entity.Item{

      "title":?e.ChildText("h3.t?>?a"),

      "url":???e.ChildAttr("h3.t?>?a",?"href"),

      }

      //?打印抓取結果

      fmt.Println(item)

      //?取消注釋調用?Crawlab?Go?SDK?存入數據庫

      //_?=?crawlab.SaveItem(item)

      強大高效而精簡易用的Golang爬蟲框架Colly,能否取代 Scrapy?

      })

      //?分頁鉤子函數

      c.OnHTML("a.n",?func(e?*colly.HTMLElement)?{

      _?=?c.Visit("https://www.baidu.com"?+?e.Attr("href"))

      })

      //?訪問初始?URL

      startUrl?:=?"https://www.baidu.com/s?wd=crawlab"

      _?=?c.Visit(startUrl)

      //?等待爬蟲結束

      c.Wait()

      }

      上面這個爬蟲腳本,僅有 40 行代碼。如果要用 Scrapy 來完成同樣的功能,可能需要更多代碼和文件目錄。

      可以從代碼中看到,Colly 的爬蟲程序編寫非常簡單,主要包含四個部分:

      生成 Colly 采集器(Collector)c,并傳入一些配置信息;

      OnHTML 鉤子函數,包含 colly.HTMLElement 元素實例,這里主要是處理抓取結果的邏輯;

      c.Visit 訪問函數,類似 Scrapy 中的 yield scrapy.Request;

      c.Wait 等待函數,等待 Colly 爬蟲程序執行完畢。

      創建好之后,在所在目錄執行 go run baidu_spider.go,即可運行百度搜索 “crawlab” 關鍵詞爬蟲。運行結果類似如下。

      ...

      map[title:docker安裝爬蟲管理工具crawlab?-?kindvampire?-?博客園?url:http://www.baidu.com/link?url=ueCY-MwzzGwaVqXw3Q18Fz8rEodI1P_mv60lRd8H0UZdFC4xVnVwWtsh-HpiwaOFI1zVjZFeVca]

      map[title:crawlab?python腳本關聯mongodb結果集,實例_kai4024589..._CSDN博客?url:http://www.baidu.com/link?url=2wFQZaLoEk7OOTHrf1LOJcPiBAZEFETQYbjrqnrJi_Wfqdx-gPFIyjt2q3f7lTC-8A6SWz_l8zE6D8SBs1j0c4DOIwbdAw8i]

      map[title:手把手教你如何用Crawlab構建技術文章聚合平臺(一)_wei..._CSDN博客?url:http://www.baidu.com/link?url=nr9NOz2dqYFuaU5E1Zjz0OIfeeixSADNBNcHwj4dw9zypIky-9dVxd4RdzdS8-JMP7_X-LYpo0ydWmB8VNBmqq]

      map[title:tikazyq-crawlab-master?crawlab爬蟲平臺?適合scrapy分布式部署...?url:http://www.baidu.com/link?url=VibsGu0BinYAUR_96pWCmcELObAXIPn7rKprlc9HR_607_cuEbxlcShUHqXjOoV6dnc4pND5F0K]

      map[title:手把手教你如何用Crawlab構建技術文章聚合平臺(一)?-?個人文章...?url:http://www.baidu.com/link?url=SG6dJcLc20xIuiesjRIXu2XzGSR0N674BEnUTveJhYe5mRc9SFtggk-NL0pmAAa]

      map[title:爬蟲管理平臺Crawlab?v0.3.0發布(Golang版本)?-?個人文章...?url:http://www.baidu.com/link?url=TItw3zWB4jHCoGmoQMm01E7oP2WlwfX7BRMsA9WDhaxHeQZZDi3I8bZh_kgTfpNx4fhtf42_]

      map[title:Crawlab?單節點服務集群搭建部署簡明教程?-?個人文章?-?Segment...?url:http://www.baidu.com/link?url=cuYEFA1zjqK1GiEmDCjwRMLDGFVKDsz6u4ljYjQol-VwDdr_cBS9Y3UlgChkyCuO7A_]

      ...

      你可能會納悶,Pipeline 和 Middleware 等 Scrapy 中定義的模塊去哪里了?其實,你需要注意的是,這些模塊并不是必須的,只是大佬們在開發爬蟲過程中總結出來的一些實用的邏輯,抽象出來了而已。如果要在 Colly 中實現 Pipeline,直接在 c.OnHTML 鉤子函數中的回調函數中調用一下后續處理函數即可,例如下面代碼。

      ...

      c.OnHTML(".result.c-container",?func(e?*colly.HTMLElement)?{

      item?:=?entity.Item{

      "title":?e.ChildText("h3.t?>?a"),

      "url":???e.ChildAttr("h3.t?>?a",?"href"),

      }

      //?后續處理抓取結果

      PostProcess(item)

      })

      ...

      從這個例子中,你可以看到 Colly 的 API 非常簡單、清爽,而正是這種簡單賦予了其極高的靈活性(Flexibility),讓開發者可以在框架內做很多復雜的事情。

      當然,Colly 也是有缺點的。從目前的開發進度來看,Colly 似乎還無法支持動態渲染內容的抓取,例如 Ajax 數據渲染,而這個在 Scrapy 中是有現成的不少解決方案的。不過從最近的 Github 上的 Pull Request 來看,支持動態渲染內容應該會很快支持 chromedp 了,也就是支持調用 Chromium 來運行 JavaScript 內容。另外,Colly 似乎還缺少 Scrapy 中內置的日志系統和數據統計模塊,似乎有些過于輕量化。

      不過,我們有理由相信,隨著今后不斷迭代,Colly 會變得越來越全面和強大的。

      與 Crawlab 集成

      Crawlab 是支持任何語言和框架的分布式爬蟲管理平臺,理論上能運行所有類型的爬蟲,包括 Colly 和 Scrapy。對 Crawlab 不了解的朋友可以查看 Crawlab 官網 以及 Github 首頁)。

      首先利用 Crawlab CLI 將爬蟲文件上傳。

      ~/projects/tikazyq/colly-crawlers/baidu(master*)???crawlab?upload

      go.mod

      go.sum

      baidu_spider.go

      uploaded?successfully

      然后在 Crawlab 的爬蟲詳情界面中輸入執行命令 go run baidu_spider.go,點擊 “運行” 開啟爬蟲。然后爬蟲就會開始運行。

      等待一段時間,爬蟲運行結束。我們可以在日志中看到打印出來的結果。

      并且,我們還可以在 “結果” 中查看抓取到的結果數據。這些結果是默認保存在 MongoDB 數據庫里的。

      因此,用 Crawlab 來管理 Colly 爬蟲是非常方便的。

      總結

      本文從介紹知名爬蟲框架 Scrapy 的優缺點開始,引入了基于 Golang 的高效而簡單的爬蟲框架 Colly。然后我們用一個百度搜索引擎抓取的例子,闡述了 Colly 的優勢,也就是它精簡而清爽的 API 以及靜態語言的健壯性,還有很多其他實用特性。Colly 的出現,或許象征著爬蟲開發者對簡潔的追求,所謂 “大道至簡”,就是用簡單而純粹的東西創造巨大的價值。爬蟲技術的發展,是一個開發流程由復雜變簡單、而程序功能由簡單變復雜的過程。爬蟲技術經歷了 urllib/requests+BeautifulSoup 原始技術,到 Scrapy 的全能框架,再到如今的 Colly 的輕量級框架。而如今已經有不少所謂的 “低代碼” 甚至 “無代碼” 爬蟲平臺了,例如 Crawlab 可配置爬蟲、八爪魚/后羿采集器。而智能化的爬蟲抓取也在逐漸變得流行。從這個角度來看,Colly 相對于 Scrapy 應該是進步了。不過現在要說 Colly 能否取代 Scrapy 還為時過早,因為 Scrapy 還有很多優秀的特性和生態是 Colly 暫時無法替代的。但是,Colly 目前正在高速發展,逐漸被開發者所了解,隨著不斷的反饋迭代,Colly 非常有潛力成為另一個爬蟲界的必備技術。

      參考

      Colly Github: https://github.com/gocolly/colly

      Colly 文檔: https://pkg.go.dev/github.com/gocolly/colly/v2?tab=doc

      Crawlab Github: https://github.com/crawlab-team/crawlab

      Crawlab 官網: https://crawlab.cn

      Crawlab 演示: https://demo-pro.crawlab.cn

      Go Python Scrapy

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:用什么甘特圖
      下一篇:手擼一個虛擬DOM
      相關文章
      国产天堂亚洲国产碰碰| 亚洲日本韩国在线| 日韩成人精品日本亚洲| 亚洲三级中文字幕| 亚洲国产精品一区二区久久hs| 亚洲成a人片在线观看老师| 久久国产亚洲精品| 亚洲中文字幕无码爆乳| 亚洲一卡二卡三卡四卡无卡麻豆| 亚洲综合图片小说区热久久| 亚洲黄色免费电影| 亚洲综合视频在线观看| 亚洲精品在线免费看| 亚洲男人的天堂在线| 亚洲午夜国产精品| 亚洲AV无码国产精品色| 亚洲成年网站在线观看| 亚洲综合国产成人丁香五月激情| 亚洲1234区乱码| 亚洲精品人成网在线播放影院| 亚洲av永久无码精品三区在线4| 91嫩草亚洲精品| 亚洲日韩国产精品乱-久| 中国亚洲呦女专区| 亚洲欧洲日本在线观看| 亚洲真人无码永久在线观看| 亚洲中文字幕久久精品无码VA| 亚洲国产乱码最新视频| 亚洲heyzo专区无码综合| 婷婷国产偷v国产偷v亚洲| 内射无码专区久久亚洲| 亚洲乱码国产一区网址| 亚洲五月综合缴情在线观看| 亚洲熟女少妇一区二区| 亚洲最新中文字幕| 色噜噜亚洲男人的天堂| 亚洲精品无码aⅴ中文字幕蜜桃| 成人婷婷网色偷偷亚洲男人的天堂 | 亚洲成a人片在线观看日本麻豆| 久久久久亚洲AV成人网人人软件| 亚洲最大AV网站在线观看|