我写了一个简单的爬虫,看起来像这样: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
提交
取消