Go语言---并发版网页段子筛选爬虫
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
// 定义一个简单的工作池,用于限制并发
type WorkPool struct {
Workers int
Jobs chan func()
wg sync.WaitGroup
}
// 初始化工作池
func NewWorkPool(workers int) *WorkPool {
pool := &WorkPool{
Workers: workers,
Jobs: make(chan func()),
}
pool.startWorkers()
return pool
}
// 添加一个新的工作任务
func (p *WorkPool) Schedule(job func()) {
p.wg.Add(1)
go p.doJob(job)
}
// 执行工作任务
func (p *WorkPool) doJob(job func()) {
p.Jobs <- job
}
// 启动工作者
func (p *WorkPool) startWorkers() {
for i := 0; i < p.Workers; i++ {
go func() {
for {
select {
case job := <-p.Jobs:
job()
p.wg.Done()
}
}
}()
}
}
// 等待所有工作结束
func (p *WorkPool) Wait() {
p.wg.Wait()
close(p.Jobs)
}
// 爬取单个网页的工作
func crawlPage(url string, ch chan<- string) {
resp, err := http.Get(url)
if err != nil {
ch <- ""
return
}
defer resp.Body.Close()
// 这里应该是解析网页内容的代码
// ...
ch <- "网页内容"
}
func main() {
start := time.Now()
urls := []string{"http://www.example.com/page1", "http://www.example.com/page2"} // 示例URL列表
pool := NewWorkPool(8) // 创建一个工作池,最多8个工作者
results := make(chan string)
for _, url := range urls {
url := url // 为循环变量创建一个局部副本
pool.Schedule(func() {
crawlPage(url, results)
})
}
go func() {
pool.Wait()
close(results)
}()
for result := range results {
fmt.Println(result)
}
fmt.Printf("Total time taken: %s\n", time.Since(start))
}
这个代码示例展示了如何使用Go语言创建一个简单的并发网络爬虫。它使用了一个工作池来限制同时进行的工作数量,并且使用了goroutines来执行并发任务。代码中的crawlPage
函数用于模拟爬取单个网页的工作,而主函数中则是模拟了一个简单的工作流程。这个例子教会开发者如何利用Go语言的并发特性来提高程序的性能。
评论已关闭