为了账号安全,请及时绑定邮箱和手机立即绑定

几分钟后,Go crawler 在从输出通道中选择时停止

几分钟后,Go crawler 在从输出通道中选择时停止

Go
阿波罗的战车 2021-07-29 18:50:39
我写了一个简单的爬虫,看起来像这样:type SiteData struct {    // ...}func downloadURL(url string) (body []byte, status int) {    resp, err := http.Get(url)    if err != nil {        return    }    status = resp.StatusCode    defer resp.Body.Close()    body, err = ioutil.ReadAll(resp.Body)    body = bytes.Trim(body, "\x00")    return}func processSiteData(resp []byte) SiteData {    // ...}    func worker(input chan string, output chan SiteData) {    // wait on the channel for links to process    for url := range input {        // fetch the http response and status code        resp, status := downloadURL(url)        if resp != nil && status == 200 {            // if no errors in fetching link            // process the data and send             // it back            output <- processSiteData(resp)        } else {            // otherwise send the url for processing            // once more            input <- url        }    }}func crawl(urlList []string) {    numWorkers := 4    input := make(chan string)    output := make(chan SiteData)    // spawn workers    for i := 0; i < numWorkers; i++ {        go worker(input, output)    }    // enqueue urls    go func() {        for url := range urlList {            input <- url        }    }()    // wait for the results    for {        select {        case data := <-output:            saveToDB(data)        }    }}func main() {    urlList := loadLinksFromDB()    crawl(urlList)}它抓取单个网站并运行良好 - 下载数据,处理它并将其保存到数据库中。然而,几分钟(5-10)左右后,它会“卡住”,需要重新启动。该站点没有将我列入黑名单,我已经与他们进行了验证,并且可以在程序阻止后随时访问任何 url。此外,它会在所有 url 完成处理之前阻止。显然它会在列表用完时阻塞,但它远不及那个。我在这里做错了吗?我使用for { select { ... } }而不是的原因for _, _ = range urlList { // read output }是,如果处理失败,任何 url 都可以重新排队。此外,数据库似乎也不是这里的问题。任何输入都会有所帮助 - 谢谢。
查看完整描述

1 回答

  • 1 回答
  • 0 关注
  • 183 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信