0

我正在使用 colly 进行一些网络抓取,但想使用 cron 定期运行它。我确实尝试了一种基本的方法。

type scraper struct {
    coll *colly.Collector
    rc   *redis.Client
}

func newScraper(c *colly.Collector, rc *redis.Client) scraper {
    return scraper{coll: c, rc: rc}
}

func main() {
    rc := redis.NewClient(&redis.Options{
        Addr:     "localhost:3000",
        Password: "", // no password set
        DB:       0,  // use default DB
    })

    coll := colly.NewCollector()

    scrape := newScraper(coll, rc)

    c := cron.New()
    c.AddFunc("@every 10s", scrape.scrapePls)
    c.Start()

    sig := make(chan int)
    <-sig
}

func (sc scraper) scrapePls() {
    sc.coll.OnHTML(`body`, func(e *colly.HTMLElement) {
        //Extracting required content

        //Using Redis to store data
    })

    sc.coll.OnRequest(func(r *colly.Request) {
        log.Println("Visting", r.URL)
    })

    sc.coll.Visit("www.example.com")
}

它似乎不起作用,拨打一次电话并且不会定期拨打下一次电话。不确定我是否错过了什么。有没有其他可以采取的方法?

任何帮助,将不胜感激。

谢谢!

4

1 回答 1

0

c.AddFunc返回error您未检查的内容,以防泄露更多信息。

您应该能够检查其返回值,该返回值c.Entries()应为您提供有关下次调用函数的信息。

如果您不知道,您不需要完整的库来完成定期执行功能。例如,您可以这样做:

scrape := newScraper(coll, rc)

sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt)
ticker := time.NewTicker(10 * time.Second)

// Run the function initially, so we don't have to wait 10 seconds for the first run (optional).
scrapePls()
for {
    select {
    case <-ticker.C:
        // Ticker will send a message every 10 seconds
        scrapePls()

        // You can also start a go routine every time. If scrapePls takes more than the interval
        // to run this may lead to issues to due to an forever increasing number of goroutines.
        // go scrapePls()
        
    case <-sig
        return
    }
}
于 2021-11-13T11:57:51.860 回答