gocolly:如何防止重复爬行,限制为唯一 url 爬行一次
gocolly: How to Prevent duplicate crawling, restrict to unique url crawling ONCE
我正在用下面的代码试验 go-colly,它似乎多次抓取同一个 url,我如何限制为一次抓取?
我怀疑 'Parallellsim:2' 导致了重复,但是,某些抓取消息 url 每次重复超过 10 次。
可跨不同网站复制。
gocolly 精益求精。
func main() {
c := colly.NewCollector(
colly.AllowedDomains( "www.coursera.org"),
colly.Async(true),
)
c.Limit(&colly.LimitRule{
DomainGlob: "*",
Parallelism: 2,
})
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Attr("href")
e.Request.Visit(link)
})
pageCount :=0
c.OnRequest(func(r *colly.Request) {
r.Ctx.Put("url", r.URL.String())
})
// Set error handler
c.OnError(func(r *colly.Response, err error) {
log.Println("Request URL:", r.Request.URL, "failed with response:", r, "\nError:", err)
})
// Print the response
c.OnResponse(func(r *colly.Response) {
pageCount++
urlVisited := r.Ctx.Get("url")
log.Println(fmt.Sprintf("%d DONE Visiting : %s", pageCount, urlVisited))
})
baseUrl := "https://www.coursera.org"
c.Visit(baseUrl)
c.Wait()
}
如果您使用 e.Request.Visit(link)
,Ctx
会在请求之间共享,因此其他请求可能会覆盖数据。在这些情况下尝试使用 c.Visit()
。它为每个请求创建新的上下文。
此外,您不需要在上下文中存储 URL,它始终可以在 OnResponse
回调中使用 r.Request.URL
。
将您的日志消息更改为以下内容,以便能够看到真实的请求url:
log.Println(fmt.Sprintf("%d DONE Visiting : %s", pageCount, r.Request.URL))
我正在用下面的代码试验 go-colly,它似乎多次抓取同一个 url,我如何限制为一次抓取?
我怀疑 'Parallellsim:2' 导致了重复,但是,某些抓取消息 url 每次重复超过 10 次。
可跨不同网站复制。
gocolly 精益求精。
func main() {
c := colly.NewCollector(
colly.AllowedDomains( "www.coursera.org"),
colly.Async(true),
)
c.Limit(&colly.LimitRule{
DomainGlob: "*",
Parallelism: 2,
})
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Attr("href")
e.Request.Visit(link)
})
pageCount :=0
c.OnRequest(func(r *colly.Request) {
r.Ctx.Put("url", r.URL.String())
})
// Set error handler
c.OnError(func(r *colly.Response, err error) {
log.Println("Request URL:", r.Request.URL, "failed with response:", r, "\nError:", err)
})
// Print the response
c.OnResponse(func(r *colly.Response) {
pageCount++
urlVisited := r.Ctx.Get("url")
log.Println(fmt.Sprintf("%d DONE Visiting : %s", pageCount, urlVisited))
})
baseUrl := "https://www.coursera.org"
c.Visit(baseUrl)
c.Wait()
}
如果您使用 e.Request.Visit(link)
,Ctx
会在请求之间共享,因此其他请求可能会覆盖数据。在这些情况下尝试使用 c.Visit()
。它为每个请求创建新的上下文。
此外,您不需要在上下文中存储 URL,它始终可以在 OnResponse
回调中使用 r.Request.URL
。
将您的日志消息更改为以下内容,以便能够看到真实的请求url:
log.Println(fmt.Sprintf("%d DONE Visiting : %s", pageCount, r.Request.URL))