Go語言實戰案例:多協程并發下載網頁內容

本文是《Go語言100個實戰案例 · 網絡與并發篇》第6篇,實戰演示如何使用 Goroutine 和 Channel,實現多協程并發抓取網頁內容,提升網絡請求效率,為構建爬蟲、內容聚合器、API 批量采集器打下基礎。


一、實戰背景

在互聯網項目中,我們常需要批量獲取多個網頁的內容,例如:

  • ? 爬蟲程序抓取網頁 HTML
  • ? 數據聚合服務請求多個 API
  • ? 批量檢測多個 URL 的可用性

如果逐個請求(串行),效率將非常低下。Go 天生支持高并發,我們可以用 Goroutine 實現?多協程并發下載網頁內容,顯著提高吞吐能力。


二、實戰目標

我們將構建一個小型并發網頁下載器,具備以下能力:

  1. 1. 輸入一組網址列表
  2. 2. 使用 Goroutine 并發請求多個網頁
  3. 3. 使用 Channel 收集下載結果
  4. 4. 打印成功/失敗狀態與網頁內容摘要
  5. 5. 支持 WaitGroup 等待所有任務完成

三、完整代碼實現

package?mainimport?("fmt""io""net/http""strings""sync""time"
)type?Result?struct?{URL????stringStatus?stringLength?intError??error
}//?下載網頁內容并寫入結果通道
func?fetchURL(url?string,?wg?*sync.WaitGroup,?resultCh?chan<-?Result)?{defer?wg.Done()client?:=?http.Client{Timeout:?5?*?time.Second,}resp,?err?:=?client.Get(url)if?err?!=?nil?{resultCh?<-?Result{URL:?url,?Status:?"請求失敗",?Error:?err}return}defer?resp.Body.Close()body,?err?:=?io.ReadAll(resp.Body)if?err?!=?nil?{resultCh?<-?Result{URL:?url,?Status:?"讀取失敗",?Error:?err}return}resultCh?<-?Result{URL:????url,Status:?resp.Status,Length:?len(body),}
}func?main()?{urls?:=?[]string{"https://example.com","https://httpbin.org/get","https://golang.org","https://nonexistent.example.com",?//?故意的錯誤URL}var?wg?sync.WaitGroupresultCh?:=?make(chan?Result,?len(urls))//?啟動多個下載協程for?_,?url?:=?range?urls?{wg.Add(1)go?fetchURL(url,?&wg,?resultCh)}//?等待所有任務完成后關閉通道go?func()?{wg.Wait()close(resultCh)}()//?讀取結果for?res?:=?range?resultCh?{if?res.Error?!=?nil?{fmt.Printf("[失敗]?%s:%v\n",?res.URL,?res.Error)}?else?{snippet?:=?fmt.Sprintf("%d?字節",?res.Length)if?res.Length?>?0?{snippet?=?fmt.Sprintf("%s?內容預覽:%s",?snippet,?strings.TrimSpace(string([]byte(res.URL)[:min(50,?res.Length)])))}fmt.Printf("[成功]?%s:%s\n",?res.URL,?snippet)}}fmt.Println("所有網頁請求已完成。")
}func?min(a,?b?int)?int?{if?a?<?b?{return?a}return?b
}

四、輸出示例

[成功]?https://example.com:1256?字節?內容預覽:https://example.com
[成功]?https://httpbin.org/get:349?字節?內容預覽:https://httpbin.org/get
[成功]?https://golang.org:3578?字節?內容預覽:https://golang.org
[失敗]?https://nonexistent.example.com:Get?"https://nonexistent.example.com":?dial?tcp:?...
所有網頁請求已完成。

五、重點知識點講解

1. 使用?Goroutine?啟動并發請求

go?fetchURL(url,?&wg,?resultCh)

每個網頁請求都是一個輕量級的線程(協程),同時運行,最大化資源利用。


2. 使用?sync.WaitGroup?等待所有任務完成

WaitGroup?是 Goroutine 的最佳搭檔,確保主線程不會提前退出。

wg.Add(1)
defer?wg.Done()

3. 使用帶緩沖的?Channel?收集結果

resultCh?:=?make(chan?Result,?len(urls))

避免協程阻塞,收集所有結果后統一處理。


4. 設置請求超時

使用?http.Client{ Timeout: ... }?可防止因某個 URL 卡住導致整體阻塞。


5. 防止通道未關閉阻塞

一定要在所有任務完成后關閉結果通道:

go?func()?{wg.Wait()close(resultCh)
}()

六、可擴展方向

這個簡單的并發網頁下載器可以繼續擴展為:

功能方向實現建議
限制最大并發數使用帶緩沖的?chan struct{}?控制令牌
下載網頁保存文件使用?os.Create?寫入 HTML 文件
支持重試機制封裝帶重試的請求邏輯
使用?context?控制取消或超時實現更復雜的任務調度系統
支持代理設置?Transport.Proxy?實現

七、小結

通過本篇案例你掌握了:

? 使用 Goroutine 啟動并發任務
? 使用 Channel 匯總任務結果
? 使用 WaitGroup 管理協程生命周期
? 網絡請求的錯誤處理與超時機制

這為你實現一個功能完善的高并發爬蟲、網頁檢測器或 API 批量處理工具奠定了基礎。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91871.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91871.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91871.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

分享鏈接實現狀態共享

有這么一個場景&#xff1a;就是有一些列表頁面&#xff0c;然后上面是有一些篩選項的&#xff0c;我去對這個列表做了一些篩選出來一個結果&#xff0c;然后我想把這個鏈接&#xff0c;或者說把這個篩選結構給分享出去&#xff0c;讓別人在打開這個頁面的時候&#xff0c;也是…

Fay數字人如何使用GPT-SOVITS進行TTS轉換以及遇到的一些問題

一、GPT-SoVITS 簡介 GPT-SoVITS 是一款開源的語音合成&#xff08;TTS&#xff09;工具&#xff0c;結合了 GPT 模型的文本理解能力與 SoVITS&#xff08;Sound of Voice In Text-to-Speech&#xff09;的聲紋模擬技術&#xff0c;能夠實現高自然度、個性化的語音合成。它支持…

HTML 顏色值

HTML 顏色值 引言 在網頁設計和開發中,顏色是一個重要的元素,它能夠幫助用戶更好地理解內容,提升視覺效果。HTML 顏色值是用于指定網頁中元素顏色的一種標準表示方法。本文將詳細介紹 HTML 顏色值的種類、表示方法以及在實際應用中的使用技巧。 HTML 顏色值種類 HTML 顏…

關于記錄一下“bug”,在做圖片上傳的時候出現的小問題

項目場景&#xff1a;之前的話寫過csdn&#xff0c;最近出現了一些小事情&#xff0c;所以耽誤了好久沒有更新&#xff0c;最近把以前的項目拿出來然后改了下環境就出現了一些問題&#xff0c;該項目使用SpringBoot3.5 SpringMVC Mybatis-Plus3.5.0&#xff0c;然后權限控制采…

數據結構:基礎知識和鏈表①

一、概念程序數據結構算法1.描述數據存儲和操作的結構 2.操作數據對象的方法二、衡量代碼的質量和效率 無論代碼操作數據量多大&#xff0c;希望程序代碼的運行時間保持恒定 隨著數據的增長&#xff0c;程序運行時間緩慢增長隨著數據的增長&#xff0c;程序運…

進階向:自動化天氣查詢工具(API調用)

自動化天氣查詢工具&#xff08;API調用&#xff09;完全指南天氣數據是日常生活中經常需要查詢的信息之一。本教程將介紹如何使用Python編寫一個自動化天氣查詢工具&#xff0c;通過調用開放的天氣API獲取實時天氣數據。這個工具適合完全不懂編程的新手學習&#xff0c;將從最…

【ROS2】常用命令

1、目錄結構在 ROS 2 包中&#xff0c;launch、urdf、rviz&#xff08;通常指 RViz 配置文件&#xff09;、config 等文件夾應直接放在包的根目錄下&#xff08;與 robot_arm/ Python 模塊目錄同級&#xff09;。這是 ROS 2 社區的通用約定&#xff0c;便于工具&#xff08;如 …

基礎組件(三):mysql連接池

文章目錄一、MySQL連接池設計1. 連接池解決了什么問題&#xff1f;連接池的作用 &#xff08;好處&#xff09;為什么不創建多條連接而用連接池2. 同步和異步連接池的區別同步連接池&#xff08;場景局限&#xff0c;應用服務器啟動時初始化資源&#xff09;異步連接池&#xf…

FI文件包含漏洞

本地文件包含&#xff08;LFI&#xff09;文件包含開發人員將可重復使用的內容寫到單個文件中&#xff0c;使用時直接調用此文件&#xff0c;無需再次編寫&#xff0c;這種調用文件的過程一般被稱為文件包含。這樣編寫代碼能減少代碼冗余&#xff0c;降低代碼后期維護難度&…

rapidocr_web v1.0.0發布了

建立RapidOCRWeb獨立倉庫 終于將web這塊代碼移了出來&#xff0c;成立了獨立倉庫RapidOCRWeb (https://github.com/RapidAI/RapidOCRWeb )。這樣以來&#xff0c;RapidOCR倉庫下的各個衍生項目均有自己的獨立倉庫&#xff0c;可以單獨控制發版和維護。這也算是為RapidOCR減負了…

Arduino IDE離線安裝ESP8266板管理工具

文章目錄概要官網地址開發板管理地址安裝ESP8266開發板支持離線安裝額外記錄NODE啟動服務概要 Arduino IDE離線安裝ESP8266板管理工具&#xff0c;在線安裝因為網絡或者https的問題不能安裝 官網地址 Adruino&#xff1a;https://www.arduino.cc/ ESP8266項目&#xff1a;<…

兩款免費數據恢復軟件介紹,Win/Mac均可用

數據已成為我們生活與工作中不可或缺的重要組成部分。無論是珍貴的家庭照片、關鍵的工作文檔&#xff0c;還是重要的學習資料&#xff0c;都以數據的形式存儲在各類設備中。然而&#xff0c;數據丟失的情況卻時常發生&#xff0c;可能是誤操作刪除&#xff0c;可能是設備意外損…

Java開發中敏感信息加密存儲全解析:筑牢數據安全防線

Java開發中敏感信息加密存儲全解析&#xff1a;筑牢數據安全防線 一、引言 1.1 敏感信息存儲的現狀與挑戰 在數字化時代&#xff0c;數據已然成為企業和組織的核心資產之一&#xff0c;而敏感信息的存儲更是重中之重。從日常的用戶登錄密碼、身份證號碼&#xff0c;到金融領域…

list的使用和模擬

(一)list的了解 (1)簡單了解 list的文檔介紹 list是基于雙向鏈表的序列式容器&#xff0c;支持雙向迭代和任意位置的常數時間插入刪除&#xff0c;相比 array、vector 等容器在這類操作上更高效&#xff0c;但不支持隨機訪問&#xff08;訪問需線性遍歷&#xff09;且因額外…

Docker 初學者需要了解的幾個知識點 (五):建容器需要進一步了解的概念

之前在《Docker 初學者需要了解的幾個知識點》幾篇文章里&#xff0c;我們梳理了 Docker 的核心概念&#xff08;如鏡像、容器、網絡等&#xff09;&#xff0c;但在實際搭建 ThinkPHP 容器環境時&#xff0c;又遇到了一些更具體的術語和配置場景。這些內容和實操結合緊密&…

【數據結構】棧的順序存儲(整型棧、字符棧)

【數據結構】棧的順序存儲&#xff08;整型棧、字符棧&#xff09;一、棧的結構定義二、字符棧的初始化、入棧、出棧、判斷是否棧為空、獲取棧頂元素、獲取棧的當前元素個數等操作三、整型棧的初始化、入棧、出棧、判斷是否棧為空、獲取棧頂元素、獲取棧的當前元素個數等操作一…

【大模型實戰】向量數據庫實戰 - Chroma Milvus

在 RAG&#xff08;檢索增強生成&#xff09;場景中&#xff0c;非結構化數據&#xff08;文本、圖像等&#xff09;的高效檢索是核心需求。傳統關系型數據庫難以勝任&#xff0c;而向量數據庫通過將數據轉化為向量、基于相似度快速匹配&#xff0c;成為 RAG 的關鍵支撐。本文聚…

pytorch程序語句固定開銷分析

深入探索PyTorch與Python的性能微觀世界&#xff1a;量化基礎操作的固定開銷 在深度學習的性能優化工作中&#xff0c;開發者通常將目光聚焦于模型結構、算法效率和并行計算策略。然而&#xff0c;在這些宏觀優化的背后&#xff0c;構成我們代碼的每一條基礎語句——無論是PyTo…

ABP VNext + CloudEvents:事件驅動微服務互操作性

ABP VNext CloudEvents&#xff1a;事件驅動微服務互操作性 &#x1f680; &#x1f4da; 目錄ABP VNext CloudEvents&#xff1a;事件驅動微服務互操作性 &#x1f680;一、引言 ??? TL;DR&#x1f4da; 背景與動機&#x1f3d7;? 整體架構圖二、環境準備與依賴安裝 &am…

軟件測試測評公司關于HTTP安全頭配置與測試?

瀏覽器和服務器之間那幾行看不見的HTTP安全頭配置&#xff0c;往往是抵御網絡攻擊的關鍵防線。作為軟件測試測評公司&#xff0c;我們發現超過六成的高危漏洞源于安全頭缺失或誤配。別小看這些響應頭&#xff0c;它們能直接掐斷跨站腳本、點擊劫持、數據嗅探的攻擊路徑。五條命…