go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的并發(fā)網(wǎng)頁(yè)爬蟲(chóng)示例
使用 goquery 提取鏈接
首先,我們需要寫(xiě)一個(gè)函數(shù)來(lái)抓取網(wǎng)頁(yè)并提取出所有的鏈接。這里我們使用 goquery 來(lái)解析 HTML 并提取鏈接。安裝 goquery 可以使用 go get 命令:
go get github.com/PuerkitoBio/goquery
然后我們來(lái)實(shí)現(xiàn) fetchAndParse 函數(shù):
func fetchAndParse(url string) ([]string, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, err
}
var links []string
doc.Find("a").Each(func(i int, s *goquery.Selection) {
href, exists := s.Attr("href")
if exists {
links = append(links, href)
}
})
return links, nil
}并發(fā)爬取鏈接
接下來(lái),我們需要寫(xiě)一個(gè)函數(shù)來(lái)并發(fā)地爬取鏈接。我們將使用 goroutine 和 channel 來(lái)實(shí)現(xiàn)并發(fā)。為了避免同時(shí)打開(kāi)過(guò)多的 HTTP 連接,我們將同時(shí)并發(fā)的 goroutine 數(shù)量限制在一定范圍內(nèi),這可以通過(guò)使用帶緩沖的 channel 來(lái)實(shí)現(xiàn)。
func crawlLinks(startURL string) {
// 創(chuàng)建一個(gè)帶緩沖的 channel,限制同時(shí)并發(fā)的 goroutine 數(shù)量
worklist := make(chan []string, 20)
go func() { worklist <- []string{startURL} }()
seen := make(map[string]bool)
// 開(kāi)始并發(fā)爬取
for list := range worklist {
for _, link := range list {
if !seen[link] {
seen[link] = true
go func(link string) {
links, err := fetchAndParse(link)
if err == nil {
worklist <- links
}
}(link)
}
}
}
}整合到一起
最后,我們將這些函數(shù)整合到一起,創(chuàng)建我們的并發(fā)網(wǎng)頁(yè)爬蟲(chóng):
func main() {
startURL := "http://example.com"
crawlLinks(startURL)
}現(xiàn)在,你已經(jīng)有了一個(gè)簡(jiǎn)單的并發(fā)網(wǎng)頁(yè)爬蟲(chóng)。雖然這個(gè)爬蟲(chóng)還很簡(jiǎn)單,但它已經(jīng)能夠展示 Go 的并發(fā)特性。
這個(gè)爬蟲(chóng)還有很多可以改進(jìn)的地方。例如,你可以添加錯(cuò)誤處理,遵守 robots.txt,處理重定向,添加延時(shí)以避免對(duì)服務(wù)器造成過(guò)大壓力等。這些改進(jìn)都可以作為你繼續(xù)學(xué)習(xí) Go 和并發(fā)編程的練習(xí)。
以上就是go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的并發(fā)網(wǎng)頁(yè)爬蟲(chóng)示例的詳細(xì)內(nèi)容,更多關(guān)于go實(shí)現(xiàn)并發(fā)網(wǎng)頁(yè)爬蟲(chóng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Go并發(fā)編程結(jié)構(gòu)體多字段原子操作示例詳解
- Go語(yǔ)言動(dòng)態(tài)并發(fā)控制sync.WaitGroup的靈活運(yùn)用示例詳解
- 數(shù)據(jù)競(jìng)爭(zhēng)和內(nèi)存重分配Golang slice并發(fā)不安全問(wèn)題解決
- 并發(fā)安全本地化存儲(chǔ)go-cache讀寫(xiě)鎖實(shí)現(xiàn)多協(xié)程并發(fā)訪問(wèn)
- golang?waitgroup輔助并發(fā)控制使用場(chǎng)景和方法解析
- Go語(yǔ)言如何輕松編寫(xiě)高效可靠的并發(fā)程序
- go并發(fā)數(shù)據(jù)一致性事務(wù)的保障面試應(yīng)答
相關(guān)文章
Go語(yǔ)言Zap庫(kù)Logger的定制化和封裝使用詳解
這篇文章主要介紹了Go語(yǔ)言Zap庫(kù)Logger的定制化和封裝使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
GO語(yǔ)言標(biāo)準(zhǔn)錯(cuò)誤處理機(jī)制error用法實(shí)例
這篇文章主要介紹了GO語(yǔ)言標(biāo)準(zhǔn)錯(cuò)誤處理機(jī)制error用法,實(shí)例分析了錯(cuò)誤處理機(jī)制的具體用法,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12
詳解golang consul-grpc 服務(wù)注冊(cè)與發(fā)現(xiàn)
這篇文章主要介紹了詳解golang consul-grpc 服務(wù)注冊(cè)與發(fā)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
淺析Go語(yǔ)言中的緩沖區(qū)及其在fmt包中的應(yīng)用
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中的緩沖區(qū)及其在fmt包中的應(yīng)用的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2024-01-01
golang NewRequest/gorequest實(shí)現(xiàn)http請(qǐng)求的示例代碼
本文主要介紹了golang NewRequest/gorequest實(shí)現(xiàn)http請(qǐng)求的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
go語(yǔ)言搬磚之go jmespath實(shí)現(xiàn)查詢json數(shù)據(jù)
這篇文章主要為大家介紹了go語(yǔ)言搬磚之go jmespath實(shí)現(xiàn)查詢json數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
使用Go語(yǔ)言實(shí)現(xiàn)常見(jiàn)hash算法
這篇文章主要為大家詳細(xì)介紹了使語(yǔ)言實(shí)現(xiàn)各種常見(jiàn)hash算法的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考下2024-01-01

