Периодически запускаю веб-скребок Colly с использованием cron в Go

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

Похоже, он не работает, звонит один раз и периодически не делает следующий звонок. Не уверен, что я что-то упускаю. Есть ли какие-либо другие подходы, которые можно было бы предпринять?

Любая помощь будет признательна.

Спасибо!

cron go go-colly web-scraping
2021-11-13 06:06:49
1

Лучший ответ

0

c.AddFunc возвращает error которые вы не проверяете, пожалуйста, сделайте это в случае, если это откроет дополнительную информацию.

Вы должны иметь возможность проверить возврат c.Entries() что должно дать вам информацию о следующем вызове вашей функции.

В случае, если вы не знали, вам не нужна полная библиотека для периодического выполнения функции. Вы можете, например, сделать:

scrap := 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-13 11:57:51

Спасибо за решение об использовании тикера для периодического вызова. Я действительно добавил c.Записи и получил это {1 {30s} 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC 0x6efa80 0x6efa80}]. Мне это не помогло. Помогает ли это?
Adith Dev Reddy

Он все равно останавливается после первого звонка.
Adith Dev Reddy

Что за c.Entries показывает, что это запланировано, просто каждые 30 секунд, а не каждые 10. Времена все еще неинициализированы, они у нас будут установлены после первого исполнения. Что касается "он все еще останавливается после первого звонка" - Вы имеете в виду с тикером? Если это так, это означает, что вы никогда не вернетесь из scrapePls. Я рекомендую вам настроить delve и пошагово выполнить свою программу, чтобы вы могли видеть, где что-то идет не так
caveman

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................