본문 바로가기
프로그래밍_

네이버 블로그 SEO 프로젝트 - Next.js Api Route 사용

by Mocca_ 2023. 3. 26.

Next.js는 React 기반의 웹 프레임워크입니다. 주로 서버사이드렌더링 사이트를 구현하는데 사용됩니다. 서버사이드렌더링을 하는 주된 이유는 검색최적화(SEO) 때문인데요. 오늘은 Next.js API라우트를 통해 네이버를 크롤링하는 기능을 만들어보았습니다. 


[목차]

  1. Next.js API 라우트란 무엇인가?
  2. Next.js API 기본적인 예제, 원리
  3. 네이버블로그 목록 가져오기
  4. 해당 네이버블로그 글자수 및 제목 포함된 문장 가져오기

 

1. Next.js API 라우트란 무엇인가?

 

Next.js에 대해서는 지난 시간에 얘기해드렸습니다. SSR에 대한 장점도 얘기해드렸습니다.

2023.03.21 - [프로그래밍_] - 네이버 블로그 SEO 프로젝트 - 개발계획, 기술

 

오늘은 Next.js의 API 라우트에 대해서 얘기해보겠습니다. Next.js는 정확하게 말하면 프론트엔드 영역입니다. 하지만 대부분의 서비스는 웹서버는 물론 API를 당연하게 사용합니다. 대부분이 사용하는 기능을 Next.js에서 간단하게 구현하기 위해 만들었습니다. API는 백엔드의 기능인데 프레임워크 라우팅기술에 추가해서 사용할 수 있게 한 것입니다.

 

Next.js API 기술을 사용한다면 백엔드서버 없이 서버리스 함수형태로 프론트엔드에서 API를 만들고 개발할 수 있게 됩니다. 이는 생산성과 효율성에 어마어마한 도움이 됩니다. 

 

 

API route를 사용하는 방법은 간단히 pages 폴더 밑에 api 폴더를 만들고 라우팅할 코드파일을 만드시면 됩니다.  

 

pages 폴더에 api폴더를 생성
pages 폴더에 api폴더를 생성

이렇게 간단하게 설정할 수 있습니다. api폴더 내에서 원하는 라우팅 이름이 있다면 그 이름대로 파일을 만들어줍니다. 

 

2. Next.js API 기본적인 예제, 원리

 

위에서 생성한 파일과 같이 api 폴더내에 getsearchvol.js란 파일을 생성한다면 '/api/getsearchvol' 이라는 엔드포인트가 생성되게 됩니다.

export default function handler(req, res) {
  res.status(200).json({ text: 'googleSearchResult' });
}

 

getsearchvol.js 내용이라고 한다면 JSON 형식으로 text 값에 googleSearchResult가 오게됩니다. 한마디로 '/api/getsearchvol' 를 호출한다면 되돌려보내주는 백엔드 서버의 역할을 하게됩니다.

 

 

async function fetchData() {
  const response = await fetch('/api/getsearchvol');
  const data = await response.json();
  console.log(data);
}

 

프론트엔드에서는 API를 통해 가져오는 'fetch'라이브러리를 사용하여 해당 JSON 값을 가져올 수 있습니다. Next.js를 통하여 프론트엔드, 백엔드의 역할을 모두 가능하게 하는 API route를 할 수 있습니다. 

 

이러한 서버리스 함수에는 보통 클라우드 서비스를 제공하는 회사에서 주로 제공하며 AWS Lambda, Google Cloud Fuctions 등이 있습니다. 편하긴 하지만 사용량에 대해 요금이 부과되므로 무료 아니면 직접 EC2 같은 서버를 대여하여 API 백엔드 서버를 올려서 사용합니다. 

 

3. 네이버블로그 검색목록 가져오기

 

api route 구글검색
api route 구글검색

클라이언트 사이드 렌더링으로는 더 쉽게 만들 수도 있는 기능이지만 SSR에서 만들어서 다른 사람도 쓸 수 있게 만드는 것은 확실히 다른 얘기입니다. 계속 사용했던 API Route 기능을 사용해야 되는데요. 

 

우선 위와 같은 키워드를 받는 inputbox와 button을 구성해주시고 버튼을 클릭하는 이벤트로 Axios로 API를 호출하는 부분을 만들어주겠습니다. 

//index.js

<button
          onClick={() => {
            onKeywordAnalyis(keyword);
          }}
        >
          분석
</button>

//중략
  const onKeywordAnalyis = (tempKey) => {
   axios
      .get("/api/naverweb", {
        params: {
          keyword: tempKey,
        },
      })
      .then((res) => {
        setwebItem(res.data.titleitem);
        setwebLink(res.data.linkitem);
      });
  }

위의 코드는 React.js로 구성된 UI를 담당하는 부분입니다. 구글검색을 위해서 GET 방식 HTTP통신을 이용하기 위해 Axios를 사용하였습니다. 일반적인 API 호출과 같습니다. 키워드로 받아온 문자열을 받아 API 서버 쪽으로 넘겨줍니다. 

 

그 후에 /api/naverweb.js 파일을 만들어줍니다. 만든 다음 적는 코드는 다음과 같습니다. 

export default function narverweb(req, res) {

  const query = req.query;
  const { keyword } = query;

  const titleList = [];
  const linkList = [];

axios
    .get(
      "https://search.naver.com/search.naver?where=influencer&sm=tab_jum&query=" +
        encodeURI(keyword)
    )
    .then((response) => {
      // console.log(response.data)
      const $ = cheerio.load(response.data);
      const ultData = $(
        //인플루언서 참여콘텐츠
        "#_inf_content_root > div > div.keyword_challenge_wrap._fadein_target > div.challenge_wrap > ul > li"
        //인플루언서 홈
        // '#main_pack > section.sc_new.sp_influencer._inf_content_section._prs_ink_mik > div > div.keyword_challenge_wrap > div > ul > li'
      );
      // 인플루언서 참여컨텐츠가 아닐 때
      if (ultData.length > 1) {
        ultData.each((i, li) => {
          const title = $(li)
            .find(
              "div.keyword_box_wrap.api_ani_send > div.detail_box > div.dsc_area > a.name_link._foryou_trigger"
            )
            .text();
          const date2 = $(li)
            .find(
              "div.keyword_box_wrap.api_ani_send > div.detail_box > div.dsc_area > span"
            )
            .text();

          if (title != "") {
            titleList.push(title + " // 날짜 : " + date2);
            const link = $(li)
              .find(
                "div.keyword_box_wrap.api_ani_send > div.detail_box > div.dsc_area > a.name_link._foryou_trigger"
              )
              .attr("href");
            linkList.push(link);
          }
        });
      } else {
        $(
          "#main_pack > section.sc_new.sp_influencer._inf_content_section._prs_ink_mik > div > div.keyword_challenge_wrap > div > ul > li"
        ).each((i, li) => {
          const title = $(li)
            .find(
              "div.keyword_box_wrap.api_ani_send > div.detail_box > div.dsc_area > a.name_link._foryou_trigger"
            )
            .text();

          const date3 = $(li)
            .find(
              "div.keyword_box_wrap.api_ani_send.type_color > div.detail_box > div.dsc_area > span"
            )
            .text();

          if (title != "") {
            titleList.push(title + " // 날짜 : " + date3);
            const link = $(li)
              .find(
                "div.keyword_box_wrap.api_ani_send > div.detail_box > div.dsc_area > a.name_link._foryou_trigger"
              )
              .attr("href");
            linkList.push(link);
          }
        });
      }
      res.status(200).json({
        titleitem: titleList,
        linkitem: linkList,
      });
    })
    .catch((err) => {
      console.log(err);
    });
}

현재 2023년 3월 기준 네이버블로그 목록은 인플루언서 참여콘텐츠와 아닌 콘텐츠로 나눠져있으며 이것을 나눠줘야 했습니다. 웹 크롤링으로 대부분의 시간은 웹 사이트를 분석하고 어떻게 가져올지 궁리하는데 사용됩니다. 이 크롤링 사이트 방식은 언제든 바뀔 수 있으며 매번 업데이트 해야하는 상당한 노력이 요구됩니다. 

 

 

위의 코드는 블로그의 제목과 링크를 찾아서 API로 뿌려줍니다. 백엔드 기능을 수행하는 것입니다. 이 사이트를 호스팅할 수 있으며 다른 사용자도 사용할 수 있습니다. 오로지 나만 사용한다면 CSR로 하면 성능이 더 좋아질 것입니다. 

 

4. 해당 네이버블로그 글자수 및 제목 포함된 문장 가져오기

 

블로그에서 볼드체로 작성된 부분이나 제목 키워드가 문장에 포함된 경우는 핵심 문장이라고 판단했습니다. 블로그를 써본 사람은 압니다. 제목에 들어가는 키워드는 내용의 문장들을 요약해놓은 핵심키워드라는 것입니다. 

 

이런 생각에 블로그 내용에 포함된 볼드체나 제목 키워드가 포함된 문장을 요약해서 가져와주는 API 함수를 만들었습니다. 

블로그 링크 분석 글자수 핵심 키워드 문장
블로그 링크 분석 글자수 핵심 키워드 문장

글자수를 파악할 수 있고 몇 줄이 있는지 간단한 기능만 넣어보았습니다. 원래는 개인용으로만 사용하려고 했는데 호스팅까지 한번 해보자는 생각이 들어서 Vercel을 이용하여 웹호스팅도 해보았습니다. 

 

https://marcus-blog-helper-3mfo.vercel.app/

 

Marcus Blog Helper

분석구글검색검색 해주세요. * 웹문서, 인플루언서* 지식인 Copyright by marcus

marcus-blog-helper-3mfo.vercel.app

 

연관검색어 기능이나 검색 수, 사이트 수 등의 기능은 CSR을 염두하고 개발하여서 동작이 느리거나 되지 않을수도 있습니다. 웹호스팅에 대한 비용을 거의 내지 않고 있기 때문에 아직까진 돌아가긴 합니다. 

 

    const accentData = ultData.find('b')
    const textData = ultData.find('span')
    
    accentData.map((i,data) => {
      const aData = $(data).text().trim()
      aData.replace(/ /g,"")
      bArray.push(aData)
    })
    
    textData.map((i,data) => {
      const tempText = $(data).text().trim()
      tempText.replace(/ /g,"")

      titleArray.forEach(tdata => {
        if(tempText.includes(tdata)){
          console.log(tempText)
          textArray.push(tempText)
        }
      });
      sum = sum + tempText.length
    })

 

볼드체와 문장을 파싱해주는 일부분입니다. 네이버블로그 상단에 있는 글은 체류시간이나 품질면에서 우수하기 때문에 올라간 것입니다. 그렇기 때문에 SEO최적화의 핵심은 이 글을 분석하는 것입니다. 앞으로 SEO를 위해 다양한 도전을 해보려고 합니다.

 


[함께 읽으면 좋은 글]

2023.03.21 - [프로그래밍_] - 네이버 블로그 SEO 프로젝트 - 개발계획, 기술

 

네이버 블로그 SEO 프로젝트 - 개발계획, 기술

네이버 블로그를 운영하면서 주제를 찾거나 정보를 찾는데 어려움이 많았습니다. 그래서 나를 위한 네이버 블로그 SEO 웹페이지를 만들어보자고 계획합니다. 오늘은 이 웹페이지 서비스를 어떻

commnetall.tistory.com

2023.02.27 - [프로그래밍_] - Node.js 데이터 파싱 1) cheerio 설치 및 파싱

 

Node.js 데이터 파싱 1) cheerio 설치 및 파싱

저는 nodejs를 데이터 모으는데 자주 사용하는 편입니다. npm에는 수많은 모듈이 있고 간단하게 npm을 이용하여 모듈을 다운받고 사용할 수 있습니다. 이번에는 데이터 파싱에 있어서 유명한 cheerio

commnetall.tistory.com

 


 

 

 

댓글