설대회

created : Sun, 26 Jan 2020 23:57:47 +0900
modified : Sat, 26 Mar 2022 03:32:44 +0900
계개모 설대회

1. 생각의 흐름

과연 설은 무엇일까?

깨달음

2. 구체화

  1. 설 당일 네이버 실시간 검색을 1분 단위로 저장해논다.
  2. 이를 가공해서 사람들에게 보여주자! 그게 곧 설아니겠는가?

반전!

2-1. 크롤링 구현

var request = require ("request");
var fs = require("fs");
request.get({url : "https://m.search.naver.com/search.naver?sm=mtp_sug.top&where=m&query=%EC%8B%A4%EC%8B%9C%EA%B0%84%EA%B2%80%EC%83%89%EC%96%B4&acq=%EC%8B%A8&acr=0&qdt=0" }, function (err, response, body){
  fs.writeFileSync(""+Date.now(), body);
});

를 열어서 1분마다 위 코드를 실행하기로 했다.

그렇게 서버에 14시간 정도 방치해놨다.

2-2. 전처리

const fs = require('fs');
const cheerio = require('cheerio');

fs.readdir('./raw_data', (err, files) => {
  if (err)
    throw err;
  const data = files.map((filename) => {
    const body = fs.readFileSync(`./raw_data/${filename}`);
    const $ = cheerio.load(body);
    const keywords = $('._keyword');
    let retval = '';
    for (let i = 0, length = keywords.length;
      i < length;
      i += 1) {
      retval += keywords[i].children[0].data + ',';
    }
    return retval;
  }).reduce((retval, now) => retval+='\n'+now);
  
  fs.writeFileSync('data.csv', data);
});

데이터를 읽어서 오름차순의 형태로 1줄이 1분을 나타내도록 저장한다.

2-3. 시각화

나중에야 정리 (2020-04-07)

  <!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8" />
    </head>
    <body>
      <script src="./d3.min.js"></script>
      <script src="./d3.layout.cloud.js"></script>
      <script src="./wordcloud.js"></script>
    </body>
  </html>
const width = 2080, height = 1920;
const svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);
d3.csv("worddata.csv").
  then(function (data) {
    showCloud(data)
  setInterval(function() {
    showCloud(data);
  }, 10000);
});

wordScale = d3.scaleLinear().domain([0, 100]).range([0, 150]).clamp(true);

svg.append("g").attr("transform", "translate(" + width * 2 + "," + height +")");

function showCloud(data) {
  d3.layout.cloud().size([width, height])
    .words(data)
    .rotate(function(d) {
      return d.text.length > 3 ? 0 : 90;
    })
    .font("Impact")
    .fontSize(function (d) {
      return wordScale(d.frequency);
    })
    .on("end", draw)
    .start();
  function draw(words) {
    var cloud = svg.selectAll("text").data(words)

    cloud.enter()
      .append("text")
      .style("fill", "#4052")
      .attr("text-anchor", "middle")
      .style("font-size", function (d) {
        return d.size + "px";
      })
    //.attr("font-size", 1)
      .text(function (d) {
        return d.text;
      });

    cloud
      .transition()
      .duration(600)
      .style("font-size", function (d) {
        return d.size + "px";
      }).attr("transform", function (d) {
        return `translate(${d.x+width/2}, ${d.y+height/2})rotate(${d.rotate})`
    }).style("fill-opacity", 1);
  }
}

결과 이미지