如何解决for死循环阻塞问题?
来源:16-7 更多用户与去重

slkk
2020-06-10
在学习爬虫的时候,需要进行分页爬取,于是我就提前访问了一次以便获取相应页的总页数,使用了goroutines,但是爬取效率反而变慢了,还出现卡死的情况,谁能帮我看看是怎么回事?
获取城市代码:
package parser
import (
"crawler/engine"
"crawler/fetcher"
"fmt"
"github.com/PuerkitoBio/goquery"
"log"
"regexp"
"strconv"
"strings"
)
var numRe = regexp.MustCompile(`\d+`)
func ParseCity(contents []byte) engine.ParseResult {
dom, err := goquery.NewDocumentFromReader(strings.NewReader(string(contents)))
if err != nil {
log.Fatalln(err)
}
var list []string
dom.Find(".groupForum .topicTitle").Each(func(i int, selection *goquery.Selection) {
_, exists := selection.Attr("span")
var (
href string
e bool
)
if exists {
href, e = selection.Find(".topicTitleSelf a").Attr("href")
} else {
href, e = selection.Find("a").Attr("href")
}
if e {
list = append(list, href)
}
})
arr := make(chan map[string]string, 100)
flag := make(chan bool, 1)
for _, uri := range list {
go func(uri string) {
contents, err := fetcher.Fetch(uri)
if err != nil {
flag <- false
}
//获取分页
doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(contents)))
if err != nil {
flag <- false
}
size := dom.Find(".pagejump").Size()
total := 1
if size > 1 {
var page string
doc.Find(".page-number").Each(func(i int, selection *goquery.Selection) {
page = selection.Text()
})
total, _ = strconv.Atoi(numRe.FindString(page))
}
arr <- map[string]string{"total": strconv.Itoa(total), "href": uri}
}(uri)
}
var r = make(chan engine.ParseResult,100)
go func() {
for {
select {
case f := <-flag:
if !f {
continue
}
case body := <-arr:
var result engine.ParseResult
//t, _ := strconv.Atoi(body["total"])
u := body["href"]
result.Requests = append(result.Requests, engine.Request{
Url: u,
//ParseFunc: func(contents []byte) engine.ParseResult {
// return ParseProfile(contents, u, t)
//},
})
}
}
}()
for {
select {
case result:= <-r:
fmt.Printf("城市:%+v\n\r",result)
return result
}
}
}
是否是for循环一直在等待的原因?如果是,应该怎么处理呢?
写回答
2回答
-
似乎并没有人会给r送数据
112020-06-11 -
slkk
提问者
2020-06-11
感谢老师回答,给r送数据我是有写的,只是贴代码的时候在修改,所以漏掉了。我这种写法有点问题,我后面修改了,可以根据老师的架构在创建一个方法专门去获取总页数和进行分页,然后把请求链接继续放进request队列里面去,这样就不必再写单独的协程方法去获取总分页。
012021-01-17
相似问题