在今天的文章中,我將介紹如何使用 Spring 排程功能來控制我們的爬蟲模組抓取資料。
我們目前是StartupRunner 在啟動時執行一次,就結束了。但我們希望能定期抓取最新的租屋資訊,而不必每次手動重新啟動程序。這時候,我們可以使用 Spring 的排程功能來實現定期抓取的需求。
@Scheduled 注解支援多種排程表達方式。我們使用了 Cron 表達式來靈活控制執行時間。
Cron 表達式是一種時間表示法,用來設定任務在特定時間點觸發。它包含六個或七個欄位,分別表示秒、分鐘、小時、日期、月份、星期幾和年份(可選)。例如:
0 0 12 * * ? // 每天中午12點執行
0 0/5 14-16 * * ? // 每天下午2點至下午4點,每5分鐘執行一次
* 表示任意值。例如 在「分」欄位表示每分鐘。
, 用於分隔多個值。例如 1,2,3 在「分」欄位表示第1、2、3分鐘。
- 用來表示一個範圍。例如 1-5 在「時」欄位表示從凌晨1點到5點。
/ 用來表示間隔長度。例如 0/5 在「秒」欄位表示0秒開始,每隔5秒。
? 僅用於「日」和「星期」字段,表示不指定具體的值(與 類似,但更明確)。
L 僅用於「日」和「星期」字段,表示最後一天或最後一個星期幾。例如 L 在「日」欄位表示當月的最後一天。
W 僅用於「日」字段,表示最接近指定日期的工作日。例如 15W 表示最接近15號的工作日。
# 僅用於「星期」字段,表示第幾個星期幾。例如 3#2 表示第二個星期三。
以下是實作
spring必須先設置EnableScheduling。
參數檔增加排程設定,目前設定半小時執行一次。
# 排程設定
rental.crawler.schedule=0 0/30 * * * ?
記得,application.properties要引入參數檔
spring.config.import=parameter.properties
新增一個Scheduler Service,決定時間到時,要執行的動作。
那其實只要使用@Scheduled這個annotation即可完成設定。
@Service
public class RentalCrawlerScheduler {
@Autowired
RentalCrawlerService rentalCrawlerService;
@PostConstruct
public void runOnceAtStartup() {
fetchRentalData();
}
@Scheduled(cron = "${rental.crawler.schedule}")
public void scheduledCrawl() throws Exception {
fetchRentalData();
}
private void fetchRentalData() {
List<RentalCatalogDTO> list = rentalCrawlerService.fetchLatestRentalCatalog();
list.stream().forEach(obj -> rentalCrawlerService.fetchRentalDetail(obj));
}
}