GCP/Apps Script

Apps Script로 어제자 네이버 증권 시황 뉴스를 cheerio를 이용해 크롤링 해오기

whistory 2023. 1. 6. 14:13
반응형

 

 

 

 

하나 하나 붙이다보니 욕심이 생겼다.

매일아침 출근길에 증시관련 뉴스를 헤드라인만 받아보고 싶었다.

 

python에서 크롤링은 해봤는데,

apps script에서도 시도해 보았다.

 

https://finance.naver.com/news/mainnews.naver

 

주요뉴스 : 네이버 증권

관심종목의 실시간 주가를 가장 빠르게 확인하는 곳

finance.naver.com

 

 

 

 

아침 출근시간에 오늘자 뉴스를 받게되면, 뉴스가 없을것 같다.

그래서 어제자 뉴스를 조회하기로 했다.

 

 

 

 

 

https://github.com/tani/cheeriogs

 

GitHub - tani/cheeriogs: Cheerio for Google Apps Script

Cheerio for Google Apps Script. Contribute to tani/cheeriogs development by creating an account on GitHub.

github.com

 

여기서 Apps Script에서 사용할 Cheerio 의 Script ID를 제공해주었다.

 

 

 

내가 생성해서 배포한 Script가 아닌, 다른사람이 배포한 Script 를 추가한다.

 

 

https://whiseung.tistory.com/entry/Apps-Script-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EC%83%9D%EC%84%B1%ED%95%B4%EC%84%9C-%EB%8B%A4%EB%A5%B8-Apps-Script%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

Apps Script 라이브러리 생성해서 다른 Apps Script에서 사용하기

유지보수를 용이하기위해서, 공통모듈을 라이브러리로 배포하여 사용하는 방법 https://whiseung.tistory.com/entry/Apps-Script-%EA%B0%9C%EB%B0%9C%EC%9D%84-%EC%9C%84%ED%95%9C-%ED%8C%8C-%EC%84%A4%EA%B3%84 Apps Script 개발을 위

whiseung.tistory.com

 

 

 

 

function libraryUseTest() {
  const url = 'https://finance.naver.com/news/mainnews.naver';
  const content = UrlFetchApp.fetch(url).getContentText();
  const $ = Cheerio.load(content);

  console.log($);
}

 

에러없이 Cheerio 를 사용할수 있을거 같다.

 

 

 

그럼 이제 크롤링을 해야한다.

 

 

 

기사들을 보여주는 newList라는 클래스를 가진 ul의 li 들을 가져와 리스트로 만든 뒤

const $listGroup = $(".newsList").children("li");

 

 

위에서 만든 li 의 리스트 안에서 a tag 를 찾아 text를 뿌려준다.

$(this).find('a').text()

 

 

 

 

 

 

 

 

 

 

 

 

function getNaverFinanceNews() {
  const url = 'https://finance.naver.com/news/mainnews.naver';
  const content = UrlFetchApp.fetch(url).getContentText("euc-kr");    // 한글 짐방지를 위해 인코딩 처리
  const $ = Cheerio.load(content);

  const $listGroup = $(".newsList").children("li");
  const collections = []
  $listGroup.each(function(i, elem) {
    collections.push({
        data  : $(this).find('a').text()
      , link  : "<https://finance.naver.com>"+$(this).find('a').attr("href")
    })
  })

  for (i in collections) {
    const data = collections[i].data;
    const link = collections[i].link;
    console.log(data);
    console.log(link);
  }
}

 

 

헤드라인과 링크를 가져오는데 성공했다.

 

 

이제 메시지를 다듬고, 어제자 뉴스를 가져오도록 변경한다.

그리고 메세지 텍스트 수의 제한도 있기 때문에,

시황뉴스만 가져오도록 수정했다.

function goodMorningNaverFinanceNews() {
  const dateCondition = getTodayDate("yesterday");
  const url = `https://finance.naver.com/news/mainnews.naver?date=${dateCondition}`;
  const content = UrlFetchApp.fetch(url).getContentText("euc-kr");    // 한글 꺠짐방지를 위해 인코딩 처리
  const $ = Cheerio.load(content);

  const $listGroup = $(".newsList").children("li");
  const collections = []
  $listGroup.each(function(i, elem) {
    collections.push({
        data  : $(this).find('a').text()
      , link  : "<https://finance.naver.com>"+$(this).find('a').attr("href")
    })
  })
  
  var message = `${dateCondition} 시황\\r\\n`;

  for (i in collections) {
    const data = collections[i].data;
    const link = collections[i].link;
    if ( data.indexOf("시황") > 0 ) {
      message += `\\r\\n뉴스: ${data}\\r\\n링크:${link}\\r\\n`;
    }
  }
  console.log(message);
}

/**
 * Date (KST) return
 * @param {string} gubun  = 구분자 (Default / BigQuery)
 */
function getTodayDate(dateConcat) {
  var gubunValue = 0;
  if ( gubun == "start" ) {
    gubunValue = -(86400000 * 12);
  } else if ( gubun == "yesterday" ) {
    gubunValue = -(86400000 * 1);
  }

  const curr          = new Date();
  const utc           = curr.getTime() + gubunValue + (curr.getTimezoneOffset() * 60 * 1000);
  const KR_TIME_DIFF  = 9 * 60 * 60 * 1000;
  const today         = new Date(utc + (KR_TIME_DIFF));

  const dateConcat  = "-";
  const date        = today.getFullYear() + dateConcat + lpad((today.getMonth()+1), 2, '0') + dateConcat + lpad(today.getDate(), 2, '0');
  return date;
}

 

제법 그럴싸해졌다.

 

 

근데 링크를 전송하니까 

특수문자 & 뒤로 텍스트가 다 짤려버린다.

 

첫번째 링크의 office_id 부터 뒤로 다 짤려버린다.

뭐 링크가 중요한건 아니니까. 헤드라인만 봐도 되니까

 

 

 

 

 

/**
 * 네이버 증시 시황 전일자 조회
 */
function goodMorningNaverFinanceNews() {
  const dateCondition = getTodayDate("yesterday");
  const url = `https://finance.naver.com/news/mainnews.naver?date=${dateCondition}`;
  const content = UrlFetchApp.fetch(url).getContentText("euc-kr");    // 한글 꺠짐방지를 위해 인코딩 처리
  const $ = Cheerio.load(content);

  const $listGroup = $(".newsList").children("li");
  const collections = []
  $listGroup.each(function(i, elem) {
    collections.push({
        data  : $(this).find('a').text()
      , link  : replaceT("<https://finance.naver.com>"+$(this).find('a').attr("href"))
    })
  })
  
  var message = `${dateCondition} 시황\\r\\n`;

  for (i in collections) {
    const data = collections[i].data;
    const link = collections[i].link;
    if ( data.indexOf("시황") > 0 || data.indexOf("마켓") > 0 ) {
      message += `\\r\\n■ ${data}`;
    }
  }
  console.log(message);
  sendTelegramMsg(message);
}

/**
 * Date (KST) return
 * @param {string} gubun  = 구분자 (Default / BigQuery)
 */
function getTodayDate(dateConcat) {
  var gubunValue = 0;
  if ( gubun == "start" ) {
    gubunValue = -(86400000 * 12);
  } else if ( gubun == "yesterday" ) {
    gubunValue = -(86400000 * 1);
  }

  const curr          = new Date();
  const utc           = curr.getTime() + gubunValue + (curr.getTimezoneOffset() * 60 * 1000);
  const KR_TIME_DIFF  = 9 * 60 * 60 * 1000;
  const today         = new Date(utc + (KR_TIME_DIFF));

  const dateConcat  = "-";
  const date        = today.getFullYear() + dateConcat + lpad((today.getMonth()+1), 2, '0') + dateConcat + lpad(today.getDate(), 2, '0');
  return date;
}

 

 

 

 

 

내용을 하나하나 추가하는데 재미가 들려서 큰일이다.

 

 

 

 

 

 

 

 

 

 

반응형