brunch

You can make anything
by writing

C.S.Lewis

by 핑크곰 Feb 25. 2020

구글 트렌드 데이터 조회

구글 트렌드 서비스는 구글에서 제공하는 서비스의 검색 동향을 제공해 준다. 쉽게 이야기 해서 구글, 유튜브의 실시간 인기 검색어들을 찾아 볼 수 있는 서비스다.            




제공하는 기능은 크게 4가지로 다음과 같이 구성되어 있다.  

탐색 : 특정 단어로 동향 검색 (검색조건 : 국가, 기간, 카테고리, 분야[웹/이미지/뉴스/쇼핑/유튜브])

인기 급상승 검색어 : 인기가 급상승하는 검색어 동향 (검색조건 : 국가)

올해의 검색어 : 년간 검색어 통계 (검색조건 : 년도, 국가)

구독 : 메일링 서비스 (검색조건 : 주제, 국가)


이중 본글에서는 인기 급상승 검색어 데이터를 조회해서 출력하는 기능을 개발해 보도록 하겠다.




인기 급상승 검색어 메뉴를 들어가면 두개의 탭으로 구성된 화면을 확인할 수 있다.

‘일별 인기 급상승 검색어’는 지난 24시간 동안의 모든 검색어 중에서 트래픽이 크게 증가한 검색어를 표시하며, 1시간마다 업데이트된다. 검색어의 조회수, 순위 그리고 관련 기사 내용을 확인할 수 있다.            



‘실시간 인기 급상승 검색어’는 지난 24시간 동안 구글에서 인기 있었던 내용을 표시하며, 실시간으로 업데이트된다. 이는 Google 알고리즘에 의해 감지된 지식 정보 주제, 검색 관심도, 인기 급상승 YouTube 동영상 또는 Google 뉴스로 구성되어 있다. 검색어의 순위, 연관단어, 시간별 관심도 그래프와 관련 기사 내용을 확인할 수 있지만, 아쉽게도 우리나라는 이 서비스를 제공받을 수 없다.(GCP 서울 리전도 생겼는데, 이런건 좀 해주라 ㅠㅠ)            



‘실시간 인기 급상승 검색어’를 사용하면 더 재밌는(?)것들을 해볼 수 있을텐테, 아쉬운대로 본글에서는 ‘일별 인기 급상승 검색어’를 수집한다.

아쉽게도 구글 트렌드는 API를 제공하지 않는다. 열심히 GCP Console을 뒤졌지만 없더라 — _-; 그런데 구글이 그러는데는 다 이유가 있는거다.

‘실시간 인기 급상승 검색어’ 화면을 들어가보면 우측 상단에 RSS 아이콘을 확인할 수 있다. API 없이도 RSS 로 받아 볼 수 있다는거. (감정의 기복이 어마하다. API 없음 =.= -> 크롤링 해야지 ㅠㅠ -> RSS 우오오 @0@)  



대한민국을 선택하고 RSS 아이콘을 클릭해보면 인기 검색어 정보를 제공한다.


<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ht="https://trends.google.com/trends/trendingsearches/daily" version="2.0"><channel>
<title>Daily Search Trends</title>
<description>Recent searches</description>
<link>
https://trends.google.com/trends/trendingsearches/daily?geo=KR
</link>
<atom:link href="https://trends.google.com/trends/trendingsearches/daily/rss?geo=KR" rel="self" type="application/rss+xml"/><item>
<title>리버풀 대 웨스트햄</title>
<ht:approx_traffic>20,000+</ht:approx_traffic>
<description/>
<link>
https://trends.google.com/trends/trendingsearches/daily?geo=KR#%EB%A6%AC%EB%B2%84%ED%92%80%20%EB%8C%80%20%EC%9B%A8%EC%8A%A4%ED%8A%B8%ED%96%84
</link>
<pubDate>Tue, 25 Feb 2020 06:00:00 +0900</pubDate>
<ht:picture>
https://t2.gstatic.com/images?q=tbn:ANd9GcS8U0W9nntlT1CrPTU6pHUVgPZiMjmVZ8tA6mRlxo4d7sX1eG4cHlOipVFLYnZb6XVQ-9aQfZRd
</ht:picture>
<ht:picture_source>조선일보</ht:picture_source>
<ht:news_item>
<ht:news_item_title>
[EPL현장리뷰]&#39;바이날둠-살라-마네 골&#39; 리버풀, 웨스트햄에 3대2 승리 ...
</ht:news_item_title>
<ht:news_item_snippet>[안필드(영국 리버풀)=윤건양 통신원]리버풀이 웨스트햄에 역전승을 거뒀다.</ht:news_item_snippet>
<ht:news_item_url>
https://news.chosun.com/site/data/html_dir/2020/02/25/2020022500453.html
</ht:news_item_url>
<ht:news_item_source>조선일보</ht:news_item_source>
</ht:news_item>
<ht:news_item>
<ht:news_item_title>리버풀, 웨스트햄에 3-2 역전승…리그 우승 매직넘버 &#39;4&#39; | 연합뉴스</ht:news_item_title>
<ht:news_item_snippet>
(서울=연합뉴스) 안홍석 기자 = 잉글랜드 프로축구 프리미어리그(EPL)의 &#39;무패 선두&#39; 리버풀이 웨스트햄과 난투 끝에 승리하며 30년 만의 1부 리그 우승을 향한 매직&nbsp;...
</ht:news_item_snippet>
<ht:news_item_url>https://www.yna.co.kr/view/AKR20200225031000007</ht:news_item_url>
<ht:news_item_source>연합뉴스</ht:news_item_source>
</ht:news_item>
</item>



검색어(title), 조회수(ht:approx_trafiic), 대표이미지(ht:picture), 관련기사(ht:news_item) 내용들을 확인할 수 있다.

브라우저 주소창에 보이는 RSS 주소를 고이 클립보드에 모셔두자

- https://trends.google.com/trends/trendingsearches/daily/rss?geo=KR


자, 이제 본격적으로 데이터를 가져오는 프로그램을 작성해 보자. HTTP Request 관련 다양한 라이브러리를 제공하는 다양한 언어를 사용할 수 있다. 필자는 NodeJs를 활용했다.


'use strict';const _ = require('lodash');
const Q = require('q');const Parser = require('rss-parser');
const parser = new Parser({
    customFields: {
        item: ['ht:approx_traffic', 'ht:picture', 'ht:news_item']
    }
});const moment = require('moment-timezone');
moment.locale('ko');
const TIMEZONE = "Asia/Seoul";
const DATE_FORMAT = "YYYY-MM-DD";
class GoogleTrendsService {    constructor(options) {
        this._options = options || {};
        this.rss = 'https://trends.google.com/trends/trendingsearches/daily/rss?geo=KR';
    }    getDailySearchTrends() {
        var deferred = Q.defer();        parser.parseURL(this.rss)
            .then(feed => {
                let googleTrendsData = {
                    'items': []
                };                feed.items.forEach(item => {
                    let today = moment().tz(TIMEZONE).format(DATE_FORMAT);
                    let trendsDate = moment(item.isoDate).tz(TIMEZONE).format(DATE_FORMAT);                    if (today == trendsDate) {
                        googleTrendsData.items.push({
                            'title': item.title,
                            'count': item['ht:approx_traffic'],
                            'pubDate': item.pubDate,
                            'pubDateKor': moment(item.isoDate).tz(TIMEZONE).format("LLLL"),
                            'isoDate': item.isoDate,
                            'picture': item['ht:picture'],
                            'newsItemTitle': _.unescape(item["ht:news_item"]["ht:news_item_title"][0]),
                            'newsItemSnippet': _.unescape(item["ht:news_item"]["ht:news_item_snippet"][0]),
                            'newsItemUrl': item["ht:news_item"]["ht:news_item_url"][0],
                            'newsItemSource': _.unescape(item["ht:news_item"]["ht:news_item_source"][0])
                        });
                    }
                });                deferred.resolve(googleTrendsData);
            }).catch(err => {
                deferred.reject(err);
            });        return deferred.promise;
    }
}module.exports = new GoogleTrendsService();


RSS 주소를 직접 호출하여 처리하는 것도 가능하지만, 관련 라이브러리를 사용하는 것을 추천한다. (가끔, 오픈소스는 믿을 수 없다며 A to Z를 모두 직접하고 싶어 하는 개발자를 만나는데, 결론부터 말하면 미련한 짓이다. 학습이 목적이 아닌이상 집단지성을 믿어라. 당신이 실생활에 사용중인 대부분의 제품에 오픈소스가 이미 들어가 있다 -_ -;)

필자는 rss-parser라는 라이브러리를 사용했다.


워낙 간단한 소스라 주석도 없다.(가장 좋은 주석은 코드 자체임을 잊지 말자) 몇가지 주의해야 할 점은 다음과 같다.  

RSS는 정해진 필드가 있기 때문에 그외의 필드는 추가로 설정해야 한다.(위에서는 customFields 활용)

‘실시간 인기 급상승 검색어’ RSS에는 금일뿐 아니라 지난날의 데이터도 포함되어 있기 때문에, 금일 데이터만 가져오기 위해서는 날짜비교가 필요하다.(이 친절한 RSS 녀석은 UTC와 선택된 국가시간을 모두 제공한다.)

관련기사 제목(ht:news_item_title)이나 내용(ht:news_item_snippet)에는 이스케이핑 문자가 들어가 있기 때문에 이에 대한 처리가 필요하다.

아래 코드로 실행해 보면 정상적으로 데이터를 가져와 출력하는 것을 확인할 수 있다.(고마워요 RSS~)


const trendsService = require('./google_trends_service');trendsService.getDailySearchTrends()
    .then(trendsList => {
        console.log(JSON.stringify(trendsList, null, 2));
    })
    .catch(err => console.err);
;    






브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari