node js naver news API 연동하기

결과창


코드 news.js

// 네이버 검색 API예제는 블로그를 비롯 전문자료까지 호출방법이 동일하므로 blog검색만 대표로 예제를 올렸습니다.
// 네이버 검색 Open API 예제 - 블로그 검색
var express = require('express');
var app = express();

app.get('/search/news', (req, res)=> { //람다식
    const client_id = '너님들 아이디';
    const client_secret = '너님들 비번';
    const api_url = 'https://openapi.naver.com/v1/search/news?display=30&query=' + encodeURI('코인'); // json 결과
//   var api_url = 'https://openapi.naver.com/v1/search/blog.xml?query=' + encodeURI(req.query.query); // xml 결과
    // const request = require('request');
    var request = require('request');
    const option = {};
    const options = {
       url: api_url, qs: option,
       headers: {'X-Naver-Client-Id':client_id, 'X-Naver-Client-Secret': client_secret}
    };
   request.get(options, (error, response, body)=> { //function이 =>로 해결되네
     if (!error && response.statusCode == 200) {
       let newsItems = JSON.parse(body).items; //items - title, link, description, pubDate
       const newsArray = [];
       for(let i=0; i< newsItems.length; i++){
           let newsItem = {};
           newsItem.title=newsItems[i].title.replace(/(<([^>]+)>)|&quot;/ig,""); //나머지 아이템들 생략
           newsItem.link=newsItems[i].link.replace(/(<([^>]+)>)|&quot;/ig,"");
           newsItem.description=newsItems[i].description.replace(/(<([^>]+)>)|&quot;/ig,"");
           newsItem.pubDate=newsItems[i].pubDate.replace(/(<([^>]+)>)|&quot;/ig,"");
           newsArray.push(newsItem);
       }
    //    res.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});
    //    res.end(body);
    res.json(newsArray);
     } else {
       res.status(response.statusCode).end(); //출력하는 부분
       console.log('error = ' + response.statusCode);
     }
   });
 });
 app.listen(3000, function () {
   console.log('http://127.0.0.1:3000/search/news?query=검색어 app listening on port 3000!');
 });

item의 이름들은
여기서 보면 된다.
뉴스 아이템들 이름 보는 페이지

이제 뉴스를 보여주려고 한다
출력하는 방법이 매우 어려웟다..(내기준)

title을 누르면 링크를 타고 뉴스를 볼 수 있다

핵심

우리는 js로 naver api 코드들을 써놨다
이걸 rendering 해주는 것이 핵심이다.
그러면 ejs를 사용하는게 아주 간단하다.

렌더링하기

먼저 views 폴더 안에
newsList.ejs를 만든다.

그리고 ejs는 html과 java의 jsp 배울 때 썼던 <% %> 와
<%= %>를 사용한다.

newsList.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>네이버 뉴스 검색 결과</h1>
    <ul>
       <%for(var i=0;i< result.length;i++){%>
        <li># <%=i%> <br>
            <h2 style="color:blue"><a href='<%=result[i].link%>'><%=result[i].title%></a></h2><br>
        <%=result[i].description%>
        <%}   %>
    </li>
        <br>
    </ul>
</body>

</html>

이렇게 사용해준다.
result라는 것을 받을 수 있는 이유는

news.js

// 네이버 검색 API예제는 블로그를 비롯 전문자료까지 호출방법이 동일하므로 blog검색만 대표로 예제를 올렸습니다.
// 네이버 검색 Open API 예제 - 블로그 검색
var express = require('express');
var app = express();

//ejs뷰 템플레이트
//익스프레스에서 뷰 엔진을 ejs로 설정
app.set('/views',__dirname+'/views');
app.set('view engine', 'ejs');

app.get('/search/news', (req, res) => { //람다식
    const client_id = 'f9I06yzTAQxLEyAYNCIr';
    const client_secret = 'kbNXwsmN_D';
    const api_url = 'https://openapi.naver.com/v1/search/news?display=30&query=' + encodeURI('코인'); // json 결과
    //   var api_url = 'https://openapi.naver.com/v1/search/blog.xml?query=' + encodeURI(req.query.query); // xml 결과
    // const request = require('request');
    var request = require('request');
    const option = {};
    const options = {
        url: api_url, qs: option,
        headers: { 'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret }
    };
    request.get(options, (error, response, body) => { //function이 =>로 해결되네
        if (!error && response.statusCode == 200) {
            let newsItems = JSON.parse(body).items; //items - title, link, description, pubDate
            const newsArray = [];
            for (let i = 0; i < newsItems.length; i++) {
                let newsItem = {};
                newsItem.title = newsItems[i].title.replace(/(<([^>]+)>)|&quot;/ig, ""); //나머지 아이템들 생략
                newsItem.link = newsItems[i].link.replace(/(<([^>]+)>)|&quot;/ig, "");
                newsItem.description = newsItems[i].description.replace(/(<([^>]+)>)|&quot;/ig, "");
                newsItem.pubDate = newsItems[i].pubDate.replace(/(<([^>]+)>)|&quot;/ig, "");
                newsArray.push(newsItem);
            }
            //    res.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});
            //    res.end(body);
            //res.json(newsArray);
            var context ={result:newsArray};
            req.app.render('newsList', context, function (err, html) {
                if (err) {
                    console.error('뷰 렌더링 중 오류 발생 : ' + err.stack);
                    res.writeHead('200', { 'Content-Type': 'text/html;charset=utf8' });
                    res.write('<h2>뷰 렌더링 중 오류 발생</h2>');
                    res.write('<p>' + err.stack + '</p>');
                    res.end();
                    return;
                    // //결과 객체 있으면 리스트 전송 
                    // console.dir(results);
                }
                res.end(html);
            })
        } else {
            res.status(response.statusCode).end(); //출력하는 부분
            console.log('error = ' + response.statusCode);
        }
        //  return newsItems;
    });

});
app.listen(3000, function () {
    console.log('http://127.0.0.1:3000/search/news?query=검색어 app listening on port 3000!');
});

news.js의 코드를 보면

//ejs뷰 템플레이트
//익스프레스에서 뷰 엔진을 ejs로 설정
app.set('/views',__dirname+'/views');
app.set('view engine', 'ejs');

이 부분ㅇ ㅣ있는데 여기서 views라는 폴더 안에있는 .ejs파일을
뷰 엔진으로 렌더링 해줄수있도록 설정해준 것이다.,

그리고

var context ={result:newsArray};
            req.app.render('newsList', context, function (err, html) {
                if (err) {
                    console.error('뷰 렌더링 중 오류 발생 : ' + err.stack);
                    res.writeHead('200', { 'Content-Type': 'text/html;charset=utf8' });
                    res.write('<h2>뷰 렌더링 중 오류 발생</h2>');
                    res.write('<p>' + err.stack + '</p>');
                    res.end();
                    return;
                    // //결과 객체 있으면 리스트 전송 
                    // console.dir(results);
                }
                res.end(html);
            })

여기 부분에서 context는 우리가 rendering 해줄 때 보내줄 객체 이름인데
context가 정의되어있지 않아서

var context ={result:newsArray};

로 정의해주었고 result라는 이름으로 newsArray를 보내준다.
뷰 렌더링 할 때 오류날까봐 err 났을 때 어떻게할지도 적어줬음

그리고 이제 style도 적용해보겠음

style 적용


경로는 이런 상태이고

이렇게 나오게 하는 코드 전체 다 올리겠습니다

newsList.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <link href="/semantic/semantic.min.css" rel="stylesheet" />
	<script src="/semantic/semantic.min.js"></script>
    <title>Document</title>
    <style>
        * {
            padding:0;
            margin:0;
            box-sizing:border-box;
        }
        
        html {
            width:100%;
            height:100%;
        }
        
        body {
            width:100%;
            height:100%;
            color: #000;
            background-color: #fff;
        }
                
        .container {
            margin-right: auto;
            margin-left: auto;
            padding-left: 20px;
            padding-right: 20px;
        }

        #cardbox {
            width:60%;
        }

        #iconImage {
            display:inline;
            width:2em;
            height:2em;
        }
        
        .bottomArea {
            background-color:rgba(242,248,255,255) !important;
        }
    </style>
</head>
<body>
<div class="container">
    <br>
    <div class="ui raised segment">
        <a class="ui blue ribbon label">검색 리스트</a>
        <br><br>
    </div>
    <%for(var i=0;i< result.length;i++){%>
    <div class="ui blue fluid card">
        <div class="content">
            <div class="header">
                <a href="<%=result[i].link%>"><%=result[i].title%></a>
            </div>
            <div class="description">
                <br>
                <p><%=result[i].description%></p>
            </div>
            <div class="meta">
                <span class="right floated time"><%=result[i].pubDate%></span>
            </div>
        </div>
    </div>
    <%}   %>
</div>

<!-- ----------------=-=-=-------------------------------------- -->
    <h1>네이버 뉴스 검색 결과</h1>
    <ul>
       <%for(var i=0;i< result.length;i++){%>
        <li># <%=i%> <br>
            <h2 style="color:blue"><a href='<%=result[i].link%>'><%=result[i].title%></a></h2><br>
        <%=result[i].description%>
        <%}   %>
    </li>
        <br>
    </ul>
</body>

</html>

검색 기능 추가


public으로 그냥 들어갈 수 있는 이유는

app.use('/public', static(path.join(__dirname,'public')));

이거땜에..

그래서 코인 치고 검색을 하면

이렇게 나온다.

먼저 파일구조

자 그럼 코드를 공개하겠다

select.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>네이버 뉴스 검색</h1>
    <form method="GET" action="/search/news">
        <input type="text" name="query">
        <input type="submit" value="검색">
    </form>
</body>
</html>

라우터로 받을 수 있도록 /search/news로 보내준다

news.js

// 네이버 검색 API예제는 블로그를 비롯 전문자료까지 호출방법이 동일하므로 blog검색만 대표로 예제를 올렸습니다.
// 네이버 검색 Open API 예제 - 블로그 검색
var express = require('express');
var app = express();

//ejs뷰 템플레이트
//익스프레스에서 뷰 엔진을 ejs로 설정
app.set('/views',__dirname+'/views');
app.set('view engine', 'ejs');

var path=require('path');
static = require('serve-static');
app.use('/public', static(path.join(__dirname,'public')));
app.use('/semantic', static(path.join(__dirname,'semantic')));

var bodyParser = require('body-parser')
//body-parser를 이용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({extended: false}))
//body-parser를 이용해 application/json 파싱
app.use(bodyParser.json())

//라우팅
app.get('/search/news', (req, res) => { //람다식
    const client_id = 'f9I06yzTAQxLEyAYNCIr';
    const client_secret = 'kbNXwsmN_D';
    const api_url = 'https://openapi.naver.com/v1/search/news?display=30&query=' + encodeURI(req.query.query); // json 결과
    //   var api_url = 'https://openapi.naver.com/v1/search/blog.xml?query=' + encodeURI(req.query.query); // xml 결과
    var request = require('request');
    const option = {};
    const options = {
        url: api_url, qs: option,
        headers: { 'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret }
    };
    request.get(options, (error, response, body) => { //function이 =>로 해결되네
        if (!error && response.statusCode == 200) {
            let newsItems = JSON.parse(body).items; //items - title, link, description, pubDate
            const newsArray = [];
            for (let i = 0; i < newsItems.length; i++) {
                let newsItem = {};
                newsItem.title = newsItems[i].title.replace(/(<([^>]+)>)|&quot;/ig, ""); //나머지 아이템들 생략
                newsItem.link = newsItems[i].link.replace(/(<([^>]+)>)|&quot;/ig, "");
                newsItem.description = newsItems[i].description.replace(/(<([^>]+)>)|&quot;/ig, "");
                newsItem.pubDate = newsItems[i].pubDate.replace(/(<([^>]+)>)|&quot;/ig, "");
                newsArray.push(newsItem);
            }
            //    res.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});
            //    res.end(body);
            //res.json(newsArray);
            var context ={result:newsArray};
            req.app.render('newsList', context, function (err, html) {
                if (err) {
                    console.error('뷰 렌더링 중 오류 발생 : ' + err.stack);
                    res.writeHead('200', { 'Content-Type': 'text/html;charset=utf8' });
                    res.write('<h2>뷰 렌더링 중 오류 발생</h2>');
                    res.write('<p>' + err.stack + '</p>');
                    res.end();
                    return;
                    // //결과 객체 있으면 리스트 전송 
                    // console.dir(results);
                }
                res.end(html);
            })
        } else {
            res.status(response.statusCode).end(); //출력하는 부분
            console.log('error = ' + response.statusCode);
        }
        //  return newsItems;
    });

});
app.listen(3000, function () {
    console.log('http://127.0.0.1:3000/search/news?query=검색어 app listening on port 3000!');
});

만약 post방식으로 form에서 보내줄거면

var bodyParser = require('body-parser')
//body-parser를 이용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({extended: false}))
//body-parser를 이용해 application/json 파싱
app.use(bodyParser.json())

bodyParser가 필요하다

하지만 나는 get방식으로 보낼거라 필요 xx

var path=require('path');
static = require('serve-static');
app.use('/public', static(path.join(__dirname,'public')));

이걸로 public폴더를 주소창에서 /public으로 접근할 수 있도록 돕는다

newsList.ejs는 위에 올려놓은 그게 끝이다.
검색기능 추가할때 안건드렸음

검색 끝~

좋은 웹페이지 즐겨찾기