뉴스 크롤링 개선: 언론사 & 날짜 정보 추가 + 페이징 처리

RYU·2025년 6월 16일

개인 프로젝트

목록 보기
10/11

지난번에 뉴스 크롤링 기능을 JSP와 연결해 웹사이트에 출력하는 것까지는 성공했지만, 아쉬웠던 부분이 있어 이번에는 추가 기능 개선을 진행하였다.

Cotroller


//  뉴스
        if (boardId == 8) {
            try {
                List<News> allNews = newsService.crawlNews("경호", 3); // 전체 뉴스 가져오기

                int itemsInAPage = 5; // 한 페이지당 몇 개씩 보여줄지
                int totalNewsCount = allNews.size();
                int pagesCount = (int) Math.ceil((double) totalNewsCount / itemsInAPage);

                int fromIndex = (page - 1) * itemsInAPage;
                int toIndex = Math.min(fromIndex + itemsInAPage, totalNewsCount);

                // 실제 보여줄 뉴스 리스트
                List<News> pagedNews = allNews.subList(fromIndex, toIndex);

                // JSP에 넘길 값들
                model.addAttribute("newsList", pagedNews);
                model.addAttribute("pagesCount", pagesCount);
                model.addAttribute("page", page);
                model.addAttribute("board", board);
                model.addAttribute("boardId", boardId);

                return "/usr/post/newslist";

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); 
                return rq.historyBackOnView("뉴스 데이터를 불러오는데 실패했습니다.");
            }
        }
  • 기존 뉴스 출력 로직에 페이징 처리를 추가하여 페이지별로 뉴스 항목을 나누어 볼 수 있게 했다.

Service


    // 이미지가 있는 뉴스 블록 기준으로 순회
            Elements articleBlocks = doc.select("div.sds-comps-base-layout");

            for (Element block : articleBlocks) {
                // 제목, 요약, 썸네일
                Element titleTag = block.selectFirst("span.sds-comps-text-type-headline1");
                Element summaryTag = block.selectFirst("span.sds-comps-text-type-body1");
                Element imgTag = block.selectFirst("img");

                // 조상 요소: 뉴스 전체 박스
                Element newsBox = block.parent();  // 일반적으로 바로 위 부모 div

                // 언론사
                Element pressTag = newsBox.selectFirst("a[href] > span.sds-comps-text-type-body2.sds-comps-text-weight-sm");

                // 날짜
                Element dateTag = newsBox.selectFirst("span.sds-comps-profile-info-subtext span.sds-comps-text-type-body2.sds-comps-text-weight-sm");

                // 값 추출
                String title = titleTag != null ? titleTag.text() : "";
                String link = (titleTag != null && titleTag.parent() != null) ? titleTag.parent().attr("href") : "";
                String summary = summaryTag != null ? summaryTag.text() : "";
                String image = imgTag != null ? imgTag.attr("src") : "";

                String press = pressTag != null ? pressTag.text() : "언론사 없음";
                String date = dateTag != null ? dateTag.text() : "날짜 없음";

                if (!title.isEmpty()) {
                    newsList.add(new News(title, link, summary, image, press, date));
  • 기존에는 제목, 요약, 썸네일만 수집했지만, 이번에는 언론사, 날짜 정보까지 추가로 수집하도록 구현하였다.
    한 박스 내에 모든 정보가 들어있는 구조였기 때문에 조금만 변경하면 쉽게 될 줄 알았지만, 썸네일과 언론 기사 이미지가 혼동되어 잘못 가져오는 문제가 발생했다.
    그래서 제목, 요약, 썸네일은 따로, 언론사와 날짜도 각각 다른 위치에서 추출하는 방식으로 로직을 세분화했다.

오류가 많았지만, 그때마다 해결하느라 캡처를 남기지 못한 것이 아쉬울 정도로 삽질이 꽤 있었다..😢

VO


@Data
@AllArgsConstructor
public class News {

    private String title;
    private String link;
    private String summary;
    private String image;
    private String press;	// 언론사 추가
    private String date;	// 날짜 추가

}
  • News객체에 언론사(press)날짜(date) 필드를 추가하여 구조를 확장하였다.

결과

드디어 내가 가져오고 싶었던 모든 정보들이 잘 출력되는 것을 확인할 수 있었다.

  • 제목, 요약, 썸네일, 언론사, 날짜 모두 정상 출력!!!!!!!
  • 페이징 처리도 잘 작동하며, 각 페이지 클릭시 URL도 동적으로 변하고 리스트가 잘 나뉘어 보여진다.

0개의 댓글