gocolly: Как предотвратить двойное сканирование, ограничить сканирование уникальными URL ОДИН РАЗ - PullRequest
0 голосов
/ 07 мая 2020

Я экспериментировал с go -colly с приведенным ниже кодом, похоже, он сканирует один и тот же URL несколько раз, как мне ограничить сканирование за один раз?

Я подозревал, что «Parallellsim: 2» является причиной дублирования, однако некоторые URL-адреса сообщений сканирования повторялись более 10 раз каждый.

Воспроизводится на разных веб-сайтах.

gocolly худощавый и отличный.

enter image description here

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()
}

1 Ответ

2 голосов
/ 01 июня 2020

Ctx разделяется между запросами, если вы используете e.Request.Visit(link), поэтому другие запросы могут перезаписать данные. В таких ситуациях попробуйте использовать c.Visit(). Он создает новый контекст для каждого запроса.

Кроме того, вам не нужно сохранять URL-адрес в контексте, он всегда доступен в обратном вызове OnResponse с использованием r.Request.URL.

Измените сообщение журнала на следующее, чтобы видеть реальный URL-адрес запроса:

log.Println(fmt.Sprintf("%d  DONE Visiting : %s", pageCount, r.Request.URL))

...