네이버 뉴스 모아보기(curl, JS decode, http server)

김상민·2023년 12월 31일
0

Web

목록 보기
2/4
post-thumbnail

🗞 오늘의 뉴스 모아보기

페어프로그래밍을 통해 네이버 뉴스에서 최신 기사 제목을 가져오는 미션을 수행해보았다.

페어프로그래밍이란?
하나의 컴퓨터에서 두 사람이 함께 작업하는 방법
네비게이터가 전략을 제시하고, 드라이버가 실제 코드를 작성하며 이 역할을 번갈아가며 수행한다.

🍊 Pair programming rule

  • 드라이버, 네비게이터
  • 네비게이터 - 주도권을 잡고 설계, 구조에 집중해서 지시, 코드 실시간 리뷰
  • 드라이버 - 지시에 따라 코드 작성, 작성하는 모든 코드에 대해 말로 설명해가며 작업을 진행
  • 10분 단위로 역할교체

위와 같은 규칙을 정하고 미션을 시작해 보았다.

🏛 설계

뉴스를 가져오기 위한 방법을 먼저 논의해보았는데 웹 크롤링 방식과 api를 사용하는 방식을 먼저 떠올렸다.
크롤링을 위해 뉴스 페이지의 source 탭을 열어보았는데 최신기사의 경우 source 탭에 나타나지 않아 크롤링 방식을 사용할 수 없었다.
그래서 nodejs 환경에서 api요청을 해보기로 했다.

🎮 구현

curl 테스트

먼저 네이버 뉴스 network 탭의 요청을 똑같이 보내면 nodejs에서 응답을 받을 수 있는지 확인하기 위해 터미널에서 curl 요청을 했다.

curl 이란?
SHELL(커맨드라인 환경)에서 REST API(http) 테스트하기 위해 프로토콜들을 이용해 URL로 데이터를 전송하여 서버에 요청을 할 수 있는 command line tool, 라이브러리다.
Mac OS에는 기본적으로 curl 명령어 패키지가 탑재되어 있다.

최신기사를 가져오는 요청을 네트워크 탭에서 찾아서 curl요청을 보내보았다.

curl -X POST https://news.naver.com/main/mainNews.naver\?sid1\=105\&firstLoad\=Y

결과

application/json;charset=EUC-KR 형태로 인코딩된 결과들이 정상 출력 되었다.

응답 디코딩

fetch(
  "https://news.naver.com/main/mainNews.naver?sid1=105&firstLoad=Y",
  options
)
  .then((res) => res.arrayBuffer())
  .then((buffer) => {
    const decoder = new TextDecoder("euc-kr");
    const decodedRes = decoder.decode(buffer);
    const json = JSON.parse(decodedRes);
    const result = JSON.parse(json.airsResult).result["105"].map(
      (value) => value.title
    );
    console.log(result);
  });

nodejs 환경에서 fetch를 이용해 결과를 받은 후 TextDecoder로 디코딩을 했다.

TextDecoder.decode()
TextDecoder 인터페이스에서 "euc-kr"에 대한 디코더를 만들고 매개변수로 전달된 버퍼를 자바스크립트 문자열로 디코딩 해주었다.

arrayBuffer()
ArrayBuffer 형태의 프로미스를 반환한다.

화면에 표시하기

브라우저 화면에 받아온 뉴스 제목을 표시하기 위해 http server를 만들었다.

const http = require("http");

const hostname = "127.0.0.1";
const port = 3000;

const options = {
  method: "POST",
};

fetch(
  "https://news.naver.com/main/mainNews.naver?sid1=105&firstLoad=Y",
  options
)
  .then((res) => res.arrayBuffer())
  .then((buffer) => {
    const decoder = new TextDecoder("euc-kr");
    const decodedRes = decoder.decode(buffer);
    const json = JSON.parse(decodedRes);
    const result = JSON.parse(json.airsResult).result["105"].map(
      (value) => value.title
    );
    return result;
  })
  .then((titles) => {
    const server = http.createServer((req, res) => {
      res.statusCode = 200;
      res.setHeader("Content-Type", "text/html; charset=UTF-8");
      res.end(
        `<html><body><ul>${titles.reduce(
          (a, c) => a + `<li>${c}</li>`,
          ""
        )}</ul></body></html>`
      );
    });

    server.listen(port, hostname, () => {
      console.log(`Server running at http://${hostname}:${port}/`);
    });
  });

html에서 위의 js를 실행시킬 경우, 로컬 파일에서 요청을 보내기 때문에 CORS 오류가 발생한다.
하지만 서버를 만들면 다른 도메인으로의 요청이 Same-Origin Policy의 영향을 받지 않기 때문에 데이터를 받아올 수 있다.

📺 결과

🖊 회고

간단한 미션이었지만 api 요청 비동기 처리, CORS, decode, curl 등 많은 것을 배울 수 있었다.
페어프로그래밍을 통해서 동료와 함께하며 이런 것들을 짧은 시간에 알게되었고, 코드를 작성할때도 비동기 처리를 어떻게 할 건지, 배열 메서드를 어떻게 쓸건지 등 같이 논의하며 진행했던게 정말 재미있었다.

profile
성장하는 웹 프론트엔드 개발자 입니다.

0개의 댓글