본문 바로가기

Spring

Jsoup 활용 WebCrawling (웹 크롤링)

반응형

 

gradle 추가

implementation 'org.jsoup:jsoup:1.11.3'

test url

https://news.naver.com/main/list.nhn?mode=LS2D&sid2=263&sid1=101&mid=shm&date=20190612&page=1

 

분석

- chrome dev tool을 통해 소스별 구성 확인.

- Document는 Jsoup을 이용해 url을 connect시켜서 저장시키면 해당 url의 html 소스가 저장됨.

- list_body newsflash_body class 내부에 기사가 들어있으므로 doc중에 list_body newsflash_body 클래스만 따로

Element에 저장 시킴.

- elem 중에서 각 기사의 헤드는 dt영역에 저장되어 있으므로 for문을 통해 dt만 출력하도록 하는데 

이미지가 삽입된 dt도 존재하므로 이미지가 삽입된 dt의 이름을 확인

=>  photo .

따라서 dt를 출력하는 중에 class name이 photo인 dt는 제외하고 text만 뽑아내도록 한다.

 

 

소스

import java.io.IOException;


import org.jsoup.Jsoup;
import org.springframework.boot.autoconfigure.SpringBootApplication;




@SpringBootApplication
public class WebCrawling {

	public static void main(String[] args) throws IOException {
		
		
		
		String url = "https://news.naver.com/main/list.nhn?mode=LS2D&sid2=263&sid1=101&mid=shm&date=20190612&page=1";
		org.jsoup.nodes.Document doc = Jsoup.connect(url).get();
		
		
		org.jsoup.select.Elements elem = doc.select("div[class=\"list_body newsflash_body\"]");
		
		
		for(org.jsoup.nodes.Element e: elem.select("dt"))
		{
			
			if(e.className().equals("photo"))
			{
				continue;
			}
			
			System.out.println(e.text());
		}
	}

}

 

 

결과

 

 

 

DB 저장하기

 

Entity

 

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Accessors(chain = true)
@Entity
public class Article {
	
	
	@Id
	Integer id;
	
	String field;
	
	String context;

}

 

 

Repository

@Repository
public interface ArticleRepository extends JpaRepository<Article, String>{

	Article findByField(@Param("field") String field);

}

 

Service

index를 0부터 1씩 증가시키면서 id 구분해줌 

primary key 구분 안하고 그냥 저장시키면 계속 overwrite 되므로 주의 

@Service
public class WebCrawling {

	@Autowired
	ArticleRepository artirepo;
		
		
	
	
	
		
		public void crawl() 
		{
			
		
		String url = "https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=102";
		org.jsoup.nodes.Document doc;
		try {
			doc = Jsoup.connect(url).get();
			org.jsoup.select.Elements elem = doc.select("div[class=\"cluster\"]");
			
			int index = 0;
			
			for(org.jsoup.nodes.Element e: elem.select("div"))
			{
				
				if(e.className().equals("cluster_text"))
				{
					Article arti = new Article(index,"culture",e.text());
					
					Article newarti = artirepo.save(arti);
					index++;
					
					System.out.println(newarti);
					//System.out.println(e.text());
					//System.out.println();
					//System.out.println(artirepo);
					//System.out.println();
					
					
					
					
				}
				
				
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
		
		
		
		
		
		
	

		}

}
반응형