DataBase/Mongo DB

Mongo DB 7강 - 주기마다 데이터 수집 및 DB 저장

상맹 2021. 10. 1. 16:53
반응형

새 프로젝트 생성

 

NewsSaveAplication 

package com.cos.newssave;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
public class NewsSaveApplication {

	public static void main(String[] args) {
		SpringApplication.run(NewsSaveApplication.class, args);
	}

}

@EnableScheduling 사용

→ Main Thread는 서버를 계속 돌리고 있기 때문에 @EnableScheduling annotation을 사용하면 이를 간헐적으로 돌릴 수 있다.

 

작업 스케쥴러 크론(Cron) 간단 사용법

unix 계열 운영체제 (linux, MacOS 포함)를 사용하다보면 시간대별로 반복되는 작업들을 수행해야 하는 경우가 매우 자주 있다. 이때 작업들의 스케쥴링을 위해서 application을 데몬처럼 실행시켜두고

www.letmecompile.com

<예시>

 

url 예시 = https://news.naver.com/main/read.naver?mode=LSD&mid=shm&sid1=100&oid=003&aid=0000000001

 

(남해)남해군 통합브랜드 ‘사랑해요 보물섬’

【남해=뉴시스】 경남 남해군은 군내에서 생산하는 우수 농수특산물, 관광산업, 스포츠마케팅 등에 사용할 통합브랜드 '사랑해요 보물섬'. 남해군은 27일 군민 1만여명이 모인 가운데 개발 선...

news.naver.com

① Test 1

@Test
public void test1() {
	// HttpUrlConnection (자바기본), OkHttp, RestTemplate(Spring), Retrofit2
	// requests
	RestTemplate rt = new RestTemplate();
		String url = "https://news.naver.com/main/read.naver?mode=LSD&mid=shm&sid1=100&oid=003&aid=0000000001";
		String html = rt.getForObject(url, String.class);
	// System.out.println(html); // jsoup로 id : articleTitle 를 파싱해야함.
		// 1. jsoup 라이브러리 빌드 (maven)
	 Document doc = Jsoup.parse(html);
	 
	 // 2. jsoup 기본 함수 약간 학습
	Element titleElement = doc.selectFirst("#articleTitle");
	String title = titleElement.text();
		// 3. 콘솔에 제목 출력
	System.out.println(title);
}

jsoup 사용 : Beautifulsoup in python 을 자바에서 사용

 

 

jsoup: Java HTML parser, built for HTML editing, cleaning, scraping, and XSS safety

jsoup: Java HTML Parser jsoup is a Java library for working with real-world HTML. It provides a very convenient API for fetching URLs and extracting and manipulating data, using the best of HTML5 DOM methods and CSS selectors. jsoup implements the WHATWG H

jsoup.org

② Test 2

@Test
public void test2(){
	for (int i = 0; i < 11; i++){
    	System.out.println(String.format("%010d", i));
    }
}

③ Test  3

@Test
public void test3(){

	  RestTemplate rt = new RestTemplate();
      List<News> nts = new ArrayList<>();
      
      for (int i = 1; i < 11; i++) {
         String aid = String.format("%010d", aidNum);
         String url = "https://news.naver.com/main/read.naver?mode=LSD&mid=shm&sid1=100&oid=003&aid="+aid;
         String html = rt.getForObject(url, String.class);

         Document doc = Jsoup.parse(html);

         Element titleElement = doc.selectFirst("#articleTitle");
         Element timeElement = doc.selectFirst(".t11");
         String title = titleElement.text();
         String time = timeElement.text();
         
         System.out.println(title);
         System.out.println(time);
         
         News nt = News.builder()
               .title(title)
               .time(time)
               .build();
         
         nts.add(nt);
         
         aidNum ++;
      }
      assertTrue(nts.size() == 10);
      }
}

 

<News>

@Builder
@AllArgsConstructor
@Data
@Document(collection = "news")
public class News {
	@Id
	private String _id;
	
	private String title;
	private String time;
}

 

<NewsRepository>

package com.cos.newssave.domain;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface NewsRepository extends MongoRepository<News, String>{

}

<NaverCraw>

- RestTemplate 와 List 사용

- for 함수 이용하여 aid 변환 기능 구현

- joup 이용하여 파싱, select 이용하여 제목과 작성일 가져오기

- builder 를 이용하여 news에 담고 List에 추가

@Component
public class NaverCraw {

   int aidNum = 1;
   
   public List<News> collect2(){
      RestTemplate rt = new RestTemplate();
      List<News> newsList = new ArrayList<>();
      
      for (int i = 1; i < 3; i++) {
         String aid = String.format("%010d", aidNum);
         String url = "https://news.naver.com/main/read.naver?mode=LSD&mid=shm&sid1=100&oid=003&aid="+aid;
         String html = rt.getForObject(url, String.class);

         Document doc = Jsoup.parse(html);

         Element titleElement = doc.selectFirst("#articleTitle");
         Element timeElement = doc.selectFirst(".t11");
         String title = titleElement.text();
         String time = timeElement.text();
         
         //System.out.println(title);
         //System.out.println(time);
         
         News news = News.builder()
               .title(title)
               .time(time)
               .build();
         
         newsList.add(news);
         
         aidNum ++;
      }
      return newsList;
   }
}

<NewsBatch>

- @Scheduled annotation 사용해서 '주기'설정( 1000ms * 60 * 2 = 2min)

- naverCraw에서 정의한 Collect10() 함수 호출

- 이를 Repository에 저장

@RequiredArgsConstructor
@Component
public class NewsBatch {
	
	private final NewsRepository newsRepository;
	private final NaverCraw naverCraw;
	
    // 초 분 시 일 월 주
	//@Scheduled(cron = "0 2 * * * *",zone = "Asia/Seoul")
	@Scheduled(fixedDelay = 1000*60*2)
	public void newsCrawAndSave() {
		
		List<News> newsList = naverCraw.collect2();
		
		newsRepository.saveAll(newsList);
	}
}

localhost:8080/news 결과값

 

반응형

'DataBase > Mongo DB' 카테고리의 다른 글

Mongo DB 9강 - 샤딩 시스템 구성 (Git Bash)  (0) 2021.10.06
Mongo DB 8강 - 샤딩  (0) 2021.10.06
Mongo DB 6강 - 배열 연산자 (고급)  (0) 2021.09.27
Mongo DB 5강 - Update, Remove  (0) 2021.09.24
Mongo DB 4강 - Save, Find, 연산  (0) 2021.09.23