ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 뉴스 정보를 가져와 보자(크롤링, 네이버 뉴스 API 사용법)
    프로젝트/게시판 프로젝트 2022. 5. 25. 14:18

    크롤링이란?

    Crwaling 사전적으로는 포복, 기다 라는 의미를 가지고 있으며 전산 쪽에서는 Web상을 돌아다니면서 정보를 수집하는 행위를 뜻합니다.

     

    웹 크롤링, 스파이더링, 스크래핑, 데이터 긁기 등 다양한 단어로 불리기도 합니다.

     

    크롤링 대상

    크롤링의 대상은 Web상의 자원들입니다.

    이 자원은 정적인 문서가 될 수 있고, API와 같은 서비스가 될 수 있습니다.

    어느 쪽이던 다수의 데이터를 수집하고 여기서 필요한 정보만 추출하게 됩니다.

     

    현재 진행하는 프로젝트에서는 어떤 키워드에 대한 네이버 뉴스데이터를 수집해보려고 합니다.

     

    크롤링하기 전 주의 사항

    개인정보가 들어있는 사이트들은 크롤링이 안 되도록 막고 싶을 수 있습니다.

    무분별한 크롤링을 막고 제어하기 위해 1994년 6월 로봇 배제 규약이 만들어졌습니다.

     

    말 그대로 로봇이 수집을 못하게 막을 목적으로 만들어졌으며 크롤링 허가/불허의 여부를 권고합니다.

     

    1) 네이버(Naver) 뉴스(http://news.naver.com/robots.txt)

    네이버 뉴스의 경우 아래와 같이 모든 로봇을 차단하고 있기 때문에 크롤링이 가능하지 않습니다.

    User-agent: Yeti
    Allow: /main/imagemontage
    Disallow: /
    User-agent: *
    Disallow: /

    2) 다음(Daum) 뉴스(http://media.daum.net/robots.txt)

    다음 뉴스는 robots.txt에 대한 정보를 제공하지 않고 있습니다.

    하지만 특정 검색 기능을 제공하지 않고 있습니다.

     

    3. 구글(Google) 뉴스(https://news.google.com/robots.txt)

    구글 뉴스 또한 /search에 대하여 크롤링을 허용하지 않고 있기 때문에 특정 검색 기능을 활용한 크롤링이 가능하지 않습니다.

    User-agent: *
    Disallow: /
    Disallow: /search?
    Allow: /$
    Allow: /?
    Allow: /nwshp$
    Allow: /news$
    Allow: /news/$
    Allow: /news/?gl=
    Allow: /news/?hl=
    Allow: /news/?ned=
    Allow: /about$
    Allow: /about?
    Allow: /about/
    Allow: /topics/
    Allow: /publications/
    Allow: /stories/
    Allow: /swg/
    Allow: /covid19/
    
    User-agent: Googlebot
    Disallow: /topics/
    Disallow: /publications/
    Disallow: /stories/

     

     

    네이버 뉴스 API 사용하기

    유명한 3개의 페이지들에서 특정 키워드를 통해 크롤링하는 것이 힘들어 보입니다.

     

    어떻게 해야 할까요?

    네이버에서는 뉴스 검색 결과를 출력해주는 REST API를 제공합니다.

     

    https://developers.naver.com/docs/search/news/

     

    검색 API 뉴스 검색 개발가이드

    NAVER Developers - 검색 API 뉴스 검색 개발가이드

    developers.naver.com

     

    그러면 네이버 검색 API 중 뉴스 검색을 사용해 보겠습니다.

     

    1. 오픈 API 이용 신청합니다

    2. 신청이 완료되면 다음과 같은 화면을 볼 수 있습니다.

    3. Document를 보고 적용해봅니다.

    https://developers.naver.com/docs/serviceapi/search/blog/blog.md#%EB%B8%94%EB%A1%9C%EA%B7%B8

     

    블로그 - Search API

    블로그 NAVER Developers - 검색 API 블로그 검색 개발가이드 검색 > 블로그 네이버 블로그 검색 결과를 출력해주는 REST API입니다. 비로그인 오픈 API이므로 GET으로 호출할 때 HTTP Header에 애플리케이션

    developers.naver.com

     

    현재 수행해야 할 작업은 뉴스 검색을 원합니다.

    하지만 블로그 부분에서 전체적인 JAVA 코드를 제공하고 있습니다.

    블로그 코드 부분을 활용하여 뉴스 검색 부분으로 변경하여 보겠습니다.

     

    실제로 주석으로 다음과 같이 적혀 있습니다.

    네이버 검색 API예제는 블로그를 비롯 전문자료까지 호출 방법이 동일하므로 blog검색만 대표로 예제로 올렸습니다.

     

    블로그 검색 예제 코드

    네이버 검색 API예제는 블로그를 비롯 전문자료까지 호출방법이 동일하므로 blog검색만 대표로 예제를 올렸습니다.
    // 네이버 검색 API 예제 - blog 검색
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLEncoder;
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class ApiExamSearchBlog {
    
    
        public static void main(String[] args) {
            String clientId = "YOUR_CLIENT_ID"; //애플리케이션 클라이언트 아이디값"
            String clientSecret = "YOUR_CLIENT_SECRET"; //애플리케이션 클라이언트 시크릿값"
    
    
            String text = null;
            try {
                text = URLEncoder.encode("그린팩토리", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("검색어 인코딩 실패",e);
            }
    
    
            String apiURL = "https://openapi.naver.com/v1/search/blog?query=" + text;    // json 결과
            //String apiURL = "https://openapi.naver.com/v1/search/blog.xml?query="+ text; // xml 결과
    
    
            Map<String, String> requestHeaders = new HashMap<>();
            requestHeaders.put("X-Naver-Client-Id", clientId);
            requestHeaders.put("X-Naver-Client-Secret", clientSecret);
            String responseBody = get(apiURL,requestHeaders);
    
    
            System.out.println(responseBody);
        }
    
    
        private static String get(String apiUrl, Map<String, String> requestHeaders){
            HttpURLConnection con = connect(apiUrl);
            try {
                con.setRequestMethod("GET");
                for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
                    con.setRequestProperty(header.getKey(), header.getValue());
                }
    
    
                int responseCode = con.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출
                    return readBody(con.getInputStream());
                } else { // 에러 발생
                    return readBody(con.getErrorStream());
                }
            } catch (IOException e) {
                throw new RuntimeException("API 요청과 응답 실패", e);
            } finally {
                con.disconnect();
            }
        }
    
    
        private static HttpURLConnection connect(String apiUrl){
            try {
                URL url = new URL(apiUrl);
                return (HttpURLConnection)url.openConnection();
            } catch (MalformedURLException e) {
                throw new RuntimeException("API URL이 잘못되었습니다. : " + apiUrl, e);
            } catch (IOException e) {
                throw new RuntimeException("연결이 실패했습니다. : " + apiUrl, e);
            }
        }
    
    
        private static String readBody(InputStream body){
            InputStreamReader streamReader = new InputStreamReader(body);
    
    
            try (BufferedReader lineReader = new BufferedReader(streamReader)) {
                StringBuilder responseBody = new StringBuilder();
    
    
                String line;
                while ((line = lineReader.readLine()) != null) {
                    responseBody.append(line);
                }
    
    
                return responseBody.toString();
            } catch (IOException e) {
                throw new RuntimeException("API 응답을 읽는데 실패했습니다.", e);
            }
        }
    }

     

     

    자바 클래스를 하나 만들고 실행한다면 다음과 같은 결과가 나오게 됩니다.

    {	"lastBuildDate":"Wed, 25 May 2022 11:21:51 +0900",	"total":10062,	"start":1,	"display":10,	"items":[		{			"title":"레인지로버스포츠 광택, 대전 <b>그린팩토리<\/b>카케어",			"link":"https:\/\/blog.naver.com\/kwak4893?Redirect=Log&logNo=222729526561",			"description":"안녕하세요 #대전광택 전문점 #<b>그린팩토리<\/b>카케어 곽영문입니다. 나들이를 떠나고 싶은, 들뜨는 마음을... 대전 광택 <b>그린팩토리<\/b>카케어에서 현재 차량이 뽐낼 수 있는 최대치의 광을 끌어올릴 계획입니다. 현재... ",			"bloggername":"그린팩토리카케어 :: 블로그",			"bloggerlink":"https:\/\/blog.naver.com\/kwak4893",			"postdate":"20220512"		},		{			"title":"<b>그린팩토리<\/b>님 씨앗 파종이들",			"link":"https:\/\/blog.naver.com\/statice_t?Redirect=Log&logNo=222741930931",			"description":"송겨울 F2 (2) <b>그린팩토리<\/b>님이 나눔해주신 제라 씨앗들 파종 후 제대로 첫 소식.? https:\/\/m.blog.naver.com... 달보드레 F2 (4) 프릴프릴스윗(1) <b>그린팩토리<\/b>님 감사합니다!!! 아직 살아는 있어요!!!! 열심히 델꼬... ",			"bloggername":"草植恐龍",			"bloggerlink":"https:\/\/blog.naver.com\/statice_t",			"postdate":"20220522"		},		{			"title":"제라늄 씨앗 파종, 발아조건  (fr, <b>그린팩토리<\/b>님)",			"link":"https:\/\/blog.naver.com\/kke5825?Redirect=Log&logNo=222254719953",			"description":"때마침 <b>그린팩토리<\/b>님께서 제라늄 씨앗 나눔을 하셨답니다. 네이버 리빙판에 노출이 되어 기념 나눔을... 제라늄 씨앗 이름은 그린스프링핑크 + 송살구 (1) 클로에 f2(2) 그린베아트리체 + 스오바(2) 엔젤크리스탈... ",			"bloggername":"행복 Serenade",			"bloggerlink":"https:\/\/blog.naver.com\/kke5825",			"postdate":"20210224"		},		{			"title":"HACCP인증 창원 <b>그린팩토리<\/b> 건축 시공",			"link":"https:\/\/blog.naver.com\/cho670623?Redirect=Log&logNo=222727551309",			"description":"호수점, 그린하우스 파티마점 등에 각종 베이커리류를 제조해 공급하는 공정자동화 베이커리 공장으로 화성종합건설의 책임하에 시공되었습니다. &lt;창원 <b>그린팩토리<\/b> 건축 시공&gt; -위치 : 창원시 의창구 동읍... ",			"bloggername":"화성종합건설",			"bloggerlink":"https:\/\/blog.naver.com\/cho670623",			"postdate":"20220510"		},		{			"title":"집들이 선물 고민이라면 <b>그린팩토리<\/b> 디퓨저",			"link":"https:\/\/blog.naver.com\/nddoo_?Redirect=Log&logNo=222461701246",			"description":"바로 <b>그린팩토리<\/b> 디퓨저!! 갓성비 제품만 만들어내기로 유~~우명한 에네스티에서 나온 라인인데... 벗 갓성비 에네스티에서 만든 <b>그린팩토리<\/b> 디퓨저는 달라도 뭐가 다릅니다요. 진짜 집안 전체를 좌지우지 하는... ",			"bloggername":"뚜뚜뚜루뚜뚜뚜뚜",			"bloggerlink":"https:\/\/blog.naver.com\/nddoo_",			"postdate":"20210808"		},		{			"title":"디퓨저 추천 실내 향기 채워주는 <b>그린팩토리<\/b> 디퓨저",			"link":"https:\/\/blog.naver.com\/ym9240?Redirect=Log&logNo=222462026285",			"description":"바로 <b>그린팩토리<\/b> 디퓨저에요~ 총 4가지 향기에 은은한 향기, 넓게 퍼지는 발향력으로 가성비가... 플로랄 그린계열의 향기로 풋풋하고 화사한 꽃향기가 매력적인 향기에요 여성스러우면서도 은은한 꽃향기를... ",			"bloggername":"새벽 네시의 손톱달",			"bloggerlink":"https:\/\/blog.naver.com\/ym9240",			"postdate":"20210808"		},		{			"title":"[두근두근 첫 출근로그] 네이버 인턴이 <b>그린팩토리<\/b>에 남긴... ",			"link":"https:\/\/blog.naver.com\/nvsmartguide?Redirect=Log&logNo=222256122612",			"description":"04 입사 후 한 달간 재택근무를 했기에 더욱더 잊을 수 없는 <b>그린팩토리<\/b> 첫 대면 출근 날- 몽글몽글하고... 덕분에 <b>그린팩토리<\/b>까지 걸어가며 근처를 여유롭게 둘러보았다- 전날 눈이 내려 소복이 쌓인 눈과... ",			"bloggername":"NAVER Marketing",			"bloggerlink":"https:\/\/blog.naver.com\/nvsmartguide",			"postdate":"20210225"		},		{			"title":"제라늄키우기, 그린펄 집중탐구, 제라늄 꽃, <b>그린팩토리<\/b>변종제... ",			"link":"https:\/\/blog.naver.com\/akubee?Redirect=Log&logNo=222651756000",			"description":"요즘 <b>그린팩토리<\/b>가 꽂혀 있는 제라늄은 바로 그린펄 화형 여린 분홍 색감에 겹이 풍성하면서 바글바글한 얼굴을 가진 아이에요 화형은 동그랗지 않고 자유로운 영혼처럼 꽃잎들이 바람에 날리는 듯한 자유롭고... ",			"bloggername":"바람의 정원",			"bloggerlink":"https:\/\/blog.naver.com\/akubee",			"postdate":"20220219"		},		{			"title":"낭만 마릴린[눙지.<b>그린팩토리<\/b>]",			"link":"https:\/\/blog.naver.com\/banci3?Redirect=Log&logNo=222717215248",			"description":"울집 꽃 안피던 키다리영감~ <b>그린팩토리<\/b>님 씨앗 그린펄 파종이. 울집 파종이 중 최장수 늙은이였는데~ 역시나 이른꽃은 홑이고... 늦은꽃은 빠글이라더니..역시~ 한알 한알의 볼륨감이 너무 좋죠~ 어쩜 이리... ",			"bloggername":"낭만농장 만들기",			"bloggerlink":"https:\/\/blog.naver.com\/banci3",			"postdate":"20220501"		},		{			"title":"제라늄\/페라고늄 - 그린빈티지핑크(한국제라늄\/<b>그린팩토리<\/b>님)",			"link":"https:\/\/blog.naver.com\/colisu?Redirect=Log&logNo=222536617518",			"description":"제라늄\/페라고늄 - 그린빈티지핑크(한국제라늄\/<b>그린팩토리<\/b>님) 우리 집 노동 제라늄으로 2위에 꼽혀요. 1위는 블랙 또트리 벨벳이거든요 ㅋ 그래도 겹꽃 중에서는 그린빈티지핑크가 제일 일을 많이, 그리고 아주... ",			"bloggername":"자작나무의 멋진 오늘",			"bloggerlink":"https:\/\/blog.naver.com\/colisu",			"postdate":"20211014"		}	]}

     

    이때 주의할 점은 위에서 발급받은 클라이언트 아이디 값과 시크릿 값을 넣어주셔야 합니다.

    그렇지 않으면 다음과 같은 오류 메시지를 받게 됩니다.

    {"errorMessage":"NID AUTH Result Invalid (1000) : Authentication failed. (인증에 실패했습니다.)","errorCode":"024"}

     

    이제 블로그 검색이 잘 되는 것을 확인했기 때문에 뉴스 검색을 적용해 보겠습니다.

    https://developers.naver.com/docs/serviceapi/search/news/news.md#%EB%89%B4%EC%8A%A4

     

    뉴스 - Search API

    뉴스 NAVER Developers - 검색 API 뉴스 검색 개발가이드 검색 > 뉴스 네이버 뉴스 검색 결과를 출력해주는 REST API입니다. 비로그인 오픈 API이므로 GET으로 호출할 때 HTTP Header에 애플리케이션 등록 시

    developers.naver.com

     

    https://developers.naver.com/docs/serviceapi/search/news/news.md#%EB%89%B4%EC%8A%A4

     

    요청 URL이 블로그와 다르기 때문에 요청 URL을 수정해줍니다.

     

     

    우리는 특정 키워드로 검색하는 것을 원하기 때문에 쿼리를 추가해줍니다.

     

    또한 부동산으로 특정 키워드를 검색하고 싶습니다.

     

    블로그 -> 뉴스 검색을 위한 코드 변경 부분

    text = URLEncoder.encode("부동산", "UTF-8");
    
    String apiURL = "https://openapi.naver.com/v1/search/news.json?query=" + text;    // json 결과

     

    이제 실행해 보면 다음과 같은 결과를 얻을 수 있습니다.

    {	"lastBuildDate":"Wed, 25 May 2022 11:24:53 +0900",	"total":3740344,	"start":1,	"display":10,	"items":[		{			"title":"롯데건설, <b>부동산<\/b>개발 투자펀드 조성 통해 종합디벨로퍼 사업에 박차",			"originallink":"http:\/\/www.newswatch.kr\/news\/articleView.html?idxno=59213",			"link":"http:\/\/www.newswatch.kr\/news\/articleView.html?idxno=59213",			"description":" 롯데건설이 지속가능한 <b>부동산<\/b> 개발사업에 힘을 쏟고 있는 가운데, 지난 24일 자사 대회의실에서 케이클라비스자산운용과 '<b>부동산<\/b>개발 투자펀드를 위한 업무협약(MOU)'을 체결하며 종합디벨로퍼 사업에 박차를 가했다.... ",			"pubDate":"Wed, 25 May 2022 11:22:00 +0900"		},		{			"title":"롯데건설-케이클라비스자산운용 '<b>부동산<\/b>개발 투자펀드 위한 업무협약' 체결",			"originallink":"http:\/\/www.wsobi.com\/news\/articleView.html?idxno=163082",			"link":"http:\/\/www.wsobi.com\/news\/articleView.html?idxno=163082",			"description":"롯데건설은 지난 24일 롯데건설 본사 대회의실에서 케이클라비스자산운용과 '<b>부동산<\/b>개발 투자펀드를 위한... 등 <b>부동산<\/b> 개발사업 전 단계에 참여하고 있는 기업이다. 이번 협약으로 양사는 공동협력을 통해 '<b>부동산<\/b>스페셜... ",			"pubDate":"Wed, 25 May 2022 11:22:00 +0900"		},		{			"title":"서울 아파트 10건 중 6건 '상승 거래'…&quot;규제 완화 기대&quot;",			"originallink":"http:\/\/www.newstomato.com\/ReadNews.aspx?no=1125137&inflow=N",			"link":"http:\/\/www.newstomato.com\/ReadNews.aspx?no=1125137&inflow=N",			"description":"서울 <b>부동산<\/b> 시장을 다시 자극하고 있다는 분석이다. 25일 김회재 더불어민주당 의원이 국토교통부로부터... 김 의원은 &quot;<b>부동산<\/b> 시장의 불안 심리가 재확산할 수 있다는 우려가 나오고 있다&quot;며 &quot;<b>부동산<\/b> 시장은 심리... ",			"pubDate":"Wed, 25 May 2022 11:22:00 +0900"		},		{			"title":"'세계 경제 견인차' 中 멈췄다…도시봉쇄로 드러난 중국경제의 민낯",			"originallink":"https:\/\/view.asiae.co.kr\/article\/2022052510245068986",			"link":"https:\/\/news.naver.com\/main\/read.naver?mode=LSD&mid=sec&sid1=104&oid=277&aid=0005093975",			"description":"이 같은 판단에는 도시봉쇄 충격 이전에 이미 내재됐던 <b>부동산<\/b> 경기 침체가 반영됐다. 중국의 고도성장을 견인했던 건설·<b>부동산<\/b> 투자붐은 과도한 대출과 투기를 막겠다며 정부가 내놓은 고강도 규제와 헝다... ",			"pubDate":"Wed, 25 May 2022 11:21:00 +0900"		},		{			"title":"롯데건설-케이클라비스,<b>부동산<\/b>개발 투자펀드 협약으로 디벨로퍼 강화",			"originallink":"https:\/\/www.hankyung.com\/realestate\/article\/202205250431i",			"link":"https:\/\/news.naver.com\/main\/read.naver?mode=LSD&mid=sec&sid1=101&oid=015&aid=0004703385",			"description":"다섯번째)이 <b>부동산<\/b>개발 투자펀드 업무 협약을 체결한 뒤 기념 사진을 찍고 있다.) 롯데건설(대표 하석주)은 지난 24일 서울 잠원동 롯데건설 본사 대회의실에서 케이클라비스자산운용과 ‘<b>부동산<\/b>개발 투자펀드를 위한... ",			"pubDate":"Wed, 25 May 2022 11:21:00 +0900"		},		{			"title":"우리은행, 초고액자산가 대상 'TCE 시그니처센터' 확장 이전",			"originallink":"http:\/\/www.newsway.co.kr\/news\/view?tp=1&ud=2022052511163039735",			"link":"http:\/\/www.newsway.co.kr\/news\/view?tp=1&ud=2022052511163039735",			"description":"우리은행의 기업금융과 <b>부동산<\/b>, 세무 전문가의 협업으로 수준 높은 금융서비스를 제공하고 있다. 우리은행은 TCE시그니처센터를 기점으로 급성장 중인 국내 자산관리시장의 다양한 니즈를 충족시키기 위한 서비스를... ",			"pubDate":"Wed, 25 May 2022 11:20:00 +0900"		},		{			"title":"신한자산운용, K리츠 442억 모집 성공",			"originallink":"https:\/\/www.fetv.co.kr\/news\/article.html?no=116190",			"link":"https:\/\/www.fetv.co.kr\/news\/article.html?no=116190",			"description":"신한자산운용은 ‘신한K리츠인프라공모주목표전환형<b>부동산<\/b>투자신탁’에 442억원의 자금이 모였다고 25일 밝혔다. 이는 올해 설정된 목표전환형 펀드와 5월 출시된 공모펀드 중에서 가장 많은 금액이다. 올해 나온... ",			"pubDate":"Wed, 25 May 2022 11:20:00 +0900"		},		{			"title":"이춘희 세종시장 후보의 '주거·교통' 문제 해법은?",			"originallink":"http:\/\/www.goodmorningcc.com\/news\/articleView.html?idxno=270150",			"link":"http:\/\/www.goodmorningcc.com\/news\/articleView.html?idxno=270150",			"description":"24일, '주거·교통' 분야 공약 발표 주거: 청약제도 개선ㆍ<b>부동산<\/b> 규제 완화 세종시민 공급비율 확대로 무주택... 및 <b>부동산<\/b> 트리플 규제 완화·해제를 이뤄내겠다고 발표했다. (GMCC굿모닝충청=세종 박수빈 기자)... ",			"pubDate":"Wed, 25 May 2022 11:20:00 +0900"		},		{			"title":"전문가들, &quot;가계부채 심각, 고강도 대출규제 이어가야&quot;",			"originallink":"https:\/\/www.hankyung.com\/economy\/article\/202205248040i",			"link":"https:\/\/news.naver.com\/main\/read.naver?mode=LSD&mid=sec&sid1=101&oid=015&aid=0004703381",			"description":"가계 자산에서 <b>부동산<\/b>이 차지하는 비중이 높고 관련 대출이 많은만큼 <b>부동산<\/b> 가격 하락은 금융안정성 및 금융자산 하락으로 이어질 가능성 있다. 국내 가계부채의 GDP 대비 규모, 증가 속도가 글로벌 최고 수준이며, 부채의... ",			"pubDate":"Wed, 25 May 2022 11:19:00 +0900"		},		{			"title":"우리은행, 초고액자산가 대상 TCE 시그니처센터 확장 이전",			"originallink":"http:\/\/www.cstimes.com\/news\/articleView.html?idxno=500068",			"link":"http:\/\/www.cstimes.com\/news\/articleView.html?idxno=500068",			"description":"TCE 시그니처센터는 우리은행 초고액 자산가들을 위한 세 번째 특화 점포로 한국씨티은행에서 최우수 프라이빗뱅커(PB) 13명을 영입해 우리은행의 기업금융 및 <b>부동산<\/b>, 세무 전문가와의 협업으로... ",			"pubDate":"Wed, 25 May 2022 11:18:00 +0900"		}	]}

     

    하지만 지금 얻고 싶은 정보는 start에서 display까지의 뉴스의 제목, 본문, link를 얻고 싶습니다.

    현재 String 형태로 return 되어있기 때문에 코드를 분석하여 보겠습니다.

     

    get 메서드 분석

     private static String get(String apiUrl, Map<String, String> requestHeaders){
            HttpURLConnection con = connect(apiUrl);
            try {
                con.setRequestMethod("GET");
                for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
                    con.setRequestProperty(header.getKey(), header.getValue());
                }
    
    
                int responseCode = con.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출
                    return readBody(con.getInputStream());
                } else { // 에러 발생
                    return readBody(con.getErrorStream());
                }
            } catch (IOException e) {
                throw new RuntimeException("API 요청과 응답 실패", e);
            } finally {
                con.disconnect();
            }
        }

    헤더 정보를 세팅하고 GET을 통해 apiURl에 대한 정보를 받아옵니다.

    만약 호출이 정상적으로 진행되면 readBody() 메서드를 호출합니다.

     

     

     

    readBody 메서드 분석

     private static String readBody(InputStream body){
            InputStreamReader streamReader = new InputStreamReader(body);
    
    
            try (BufferedReader lineReader = new BufferedReader(streamReader)) {
                StringBuilder responseBody = new StringBuilder();
    
    
                String line;
                while ((line = lineReader.readLine()) != null) {
                    responseBody.append(line);
                }
    
    
                return responseBody.toString();
            } catch (IOException e) {
                throw new RuntimeException("API 응답을 읽는데 실패했습니다.", e);
            }
        }

    StringBuilder를 선언하여 responseBody에 한 줄씩 line을 append 하고  그것을 toString()으로 반환하기 때문에 우리는 한 줄로 된 String을 받게 된 것입니다.

     

    즉, 이 부분을 print 해보면 다음과 같이 출력됩니다.

    while ((line = lineReader.readLine()) != null) {
                    System.out.println(line);
                    responseBody.append(line);
    }

    line print시

    아까보다 훨씬 보기 좋아졌으며 여기서 데이터를 조작하여 객체 리스트로 넘겨준다면 이 데이터를 잘 활용할 수 있을 것 같습니다.

     

    해당 데이터를 다루기 위해 Information, Item 객체를 생성하겠습니다.

    import java.util.List;
    
    class Information{
        public String lastBuildDate;
        public int total;
        public int start;
        public int display;
        public List<Item> items;
    }
    
    class Item{
        String title;
        String originalLink;
        String link;
        String description;
        String pubData;
    
        @Override
        public String toString() {
            return "Item{" +
                    "title='" + title + '\'' +
                    ", originalLink='" + originalLink + '\'' +
                    ", link='" + link + '\'' +
                    ", description='" + description + '\'' +
                    ", pubData='" + pubData + '\'' +
                    '}';
        }
    }

     

    JSON 형식과 동일하게 객체를 생성하여 매핑해줍니다.

     

     

    다양한 라이브러리들이 있지만 Json형태의 String을 객체로 바꾸기 위해 gson 라이브러리를 사용하겠습니다.

     

    만약 maven, gradle 프로젝트가 아니라면 다음 글을 참조하셔서 프로젝트를 변경할 수 있습니다.

    https://stackoverflow.com/questions/7642456/intellij-convert-a-java-project-module-into-a-maven-project-module

     

    IntelliJ - Convert a Java project/module into a Maven project/module

    I have a project on Bitbucket. Only the sources are committed. To retrieve the project onto a new machine, I used Version Control > Checkout from Version Control from within IntelliJ. It then asks

    stackoverflow.com

     

     

    pom.xml에 maven 종속성을 추가하겠습니다

       <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.8.0</version>
    </dependency>

     

    그리고 Gson을 이용하여 Information 객체로 만들고 items를 반복하며 print 하는 코드는 다음과 같습니다

      Gson gson = new Gson();
            Information info = gson.fromJson(responseBody, Information.class);
    
            for(Item item : info.items){
                System.out.println(item.title);
                System.out.println(item.description);
                System.out.println(item.link);
                System.out.println();
            }

     

    이제 필요한 정보들만 객체에서 사용할 수 있습니다.

     

     

     

    출처

    https://gbsb.tistory.com/80

     

    크롤링(crawling) - robots.txt와 주의점

    크롤러를 만들기 전 알아야 할 사항 웹페이지의 내용을 가져 오는 것을 크롤링(Crawling) 또는 스크래핑(Scraping)이라고 합니다. 가져와야 할 페이지들이 많은 경우, 구글이나 네이버, 다음과 같은

    gbsb.tistory.com

    https://jcdgods.tistory.com/317

     

    [크롤링] 데이터 수집을 위한 크롤링 1편 : 크롤링이란 무엇인가?

    최근 블로그의 유입 로그를 봤더니 생각보다 많은 사람들이 크롤링으로 내 블로그를 들어온다는 사실을 알았다. [Java] Jsoup을 이용한 간단한 웹 크롤러 만들기, 사실 이 글은 워드프레스로 오기

    jcdgods.tistory.com

    https://excelsior-cjh.tistory.com/entry/04-Scrapy를-이용한-뉴스크롤링-하기 [EXCELSIOR:티스토리]

     

    04. Scrapy를 이용한 뉴스 크롤링 하기

    이번 포스팅은 앞의 게시글을 토대로 웹크롤링을 위한 환경설정 후 Scrapy를 이용하여 뉴스기사에 대한 크롤링을 하여 JSON, CSV, MongoDB에 저장하는 방법에 대한 글이다. 1. robots.txt (로봇 배제 표준)

    excelsior-cjh.tistory.com

    https://yookeun.github.io/java/2017/05/27/java-gson/

     

    Java에서 JSON(GSON)사용

    Java에서 간단하게 json을 생성하고 파싱하는 방법을 알아보자. 여러가지 라이브러리가 있는데 우리는 여기서 구글에서 만든 gson를 이용하겠다. gson은 비교적 가볍고, 메이븐저장소를 지원하고 전

    yookeun.github.io

    https://stackoverflow.com/questions/51350347/how-to-parse-jsonitems

     

    how to parse json(items : [{...}])

    information.json { "lastBuildDate": "Mon, 16 Jul 2018 01:28:44 +0900", "total": 2, "start": 1, "display": 2, "items": [{ "title": "<b>설빙</b> 경기광명철산점", "link": "http://sulbing.c...

    stackoverflow.com

    https://blog.kwondroid.com/16

     

    (JAVA) Naver API로 가져온 JSON을 GSON으로 Parse하기

    네이버 API를 통해 서버에서 넘어온 Json을 파싱하는 법을 알아보겠다. GSON을 이용한다. 먼저 프로젝트에 GSON을 Import하자. (설명은 여기) 그 다음 애플리케이션 등록을 하자 (등록은 여기) 자세한

    blog.kwondroid.com

     

    댓글

Designed by Tistory.