네이버 검색결과 데이터랩 검색어 트렌드

네이버 검색결과에서 데이터랩의 검색어 트렌드 정보를 확인할 수 있습니다.

目前为 2021-06-29 提交的版本。查看 最新版本

// ==UserScript==
// @namespace    https://tampermonkey.myso.kr/
// @name         네이버 검색결과 데이터랩 검색어 트렌드
// @description  네이버 검색결과에서 데이터랩의 검색어 트렌드 정보를 확인할 수 있습니다.
// @copyright    2021, myso (https://tampermonkey.myso.kr)
// @license      Apache-2.0
// @version      1.0.3
// @author       Won Choi
// @match        *://search.naver.com/search.naver?*
// @match        *://m.search.naver.com/search.naver?*
// @connect      naver.com
// @connect      ryo.co.kr
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @require      https://cdn.jsdelivr.net/npm/kr.myso.tampermonkey/assets/vendor/gm-app.min.js
// @require      https://cdn.jsdelivr.net/npm/kr.myso.tampermonkey/assets/vendor/gm-add-style.min.js
// @require      https://cdn.jsdelivr.net/npm/kr.myso.tampermonkey/assets/vendor/gm-add-script.min.js
// @require      https://cdn.jsdelivr.net/npm/kr.myso.tampermonkey/assets/vendor/gm-xmlhttp-request-async.min.js
// @require      https://cdn.jsdelivr.net/npm/kr.myso.tampermonkey/assets/donation.min.js
// @require      https://cdn.jsdelivr.net/npm/chart.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js
// ==/UserScript==

// ==OpenUserJS==
// @author myso
// ==/OpenUserJS==
function format_number(number) { return number.toString().split( /(?=(?:\d{3})+(?:\.|$))/g ).join( "," ); }
function parsed_number(number) { return /^[\d\.]+$/.test(String(number)) ? parseFloat(number) : 0; }
function json_parse(text) { try { return JSON.parse(text); } catch(e) { return text; } }
async function request(url, options = { method: 'GET' }) { return new Promise((resolve, reject) => { GM_xmlhttpRequest(Object.assign({ method: 'GET', url: url.toString(), onerror: reject, onload: resolve, }, options)); }); }
async function get_hash_keyword_trend(keyword, options = { gender: '', age: '', device: '' }) {
    if(!options.limit) options.limit = moment();
    if(!options.start) options.start = moment(options.limit).subtract(1, 'days').subtract(1, 'months');
    const headers = {
        "content-type": 'application/x-www-form-urlencoded',
        "referer": 'https://datalab.naver.com/keyword/trendSearch.naver',
    };
    const form = new URLSearchParams();
    form.append('queryGroups', `${keyword}__SZLIG__${keyword}`);
    form.append('startDate', moment(options.start).format('YYYYMMDD'));
    form.append('endDate', moment(options.limit).format('YYYYMMDD'));
    form.append('timeUnit', 'date');
    form.append('gender', options.gender);
    form.append('age', options.age);
    form.append('device', options.device);
    const data = form.toString();
    const resp = await request('https://datalab.naver.com/qcHash.naver', { headers, method: 'POST', data });
    return json_parse(resp.responseText);
}
async function get_keyword_trend(keyword, options = {}) {
    if(!options.limit) options.limit = moment();
    if(!options.start) options.start = moment(options.limit).subtract(1, 'days').subtract(1, 'months');
    const sdate = moment(options.start);
    const edate = moment(options.limit);
    const trend = _.range(edate.diff(sdate, 'days')).map((v)=>moment(options.start).add(v, 'days').format('YYYYMMDD'));
    const headers = {
      "referer": 'https://datalab.naver.com/keyword/trendSearch.naver',
    };
    const hash = await get_hash_keyword_trend(keyword);
    if(hash.message) throw new Error(hash.message);
    if(hash.success) {
        const resp = await request(`https://datalab.naver.com/qc.naver?hashKey=${hash.hashKey}`, { headers });
        const json = json_parse(resp.responseText);
        if(json.message) throw new Error(json.message);
        if(json.success) {
            const data = _.get(json, 'result[0].data', []);
            return _.reduce(trend, (r, period)=>(r.push(_.find(data, o=>o.period == period) || ({ period, value: 0 })), r), []);
        }
    }
}
async function get_keyword_count(keyword) {
    const uri = new URL('https://www.ryo.co.kr/naver/keyword?position=main&callback=update_keyword_analysis&dn=&keyword='); uri.searchParams.set('keyword', keyword);
    const res = await request(uri.toString());
    function update_keyword_analysis(data){
        const resp = {}; if(!data) return;
        resp.monthlyPcQcCnt = parsed_number(data && data.monthlyPcQcCnt);
        resp.monthlyMobileQcCnt = parsed_number(data && data.monthlyMobileQcCnt);
        resp.monthlyQcCnt = resp.monthlyPcQcCnt + resp.monthlyMobileQcCnt;
        return resp;
    }
    return eval(res.responseText);
}
async function data_normalize(keyword) {
    const stat = await get_keyword_count(keyword);
    const data = await get_keyword_trend(keyword);
    const sums = data.reduce((r, o)=>r+o.value, 0);
    const tick = stat ? (stat.monthlyQcCnt / sums) : 1;
    const items = data.map((item)=>(item.value = (item.value * tick), item));
    return { items, rval: !!stat };
}
async function main() {
    GM_donation('#container', 0);
    const keyword = (new URL(location.href)).searchParams.get('query'); if(!keyword) return;
    const data = await data_normalize(keyword);
    const pack = document.querySelector('#main_pack, #snb');
    const wrap = pack.querySelector('.section.trend') || document.createElement('section'); wrap.classList.add('section', 'trend'); pack.prepend(wrap);
    const canv = wrap.querySelector('canvas') || document.createElement('canvas'); canv.style.width = '100%'; canv.style.height = '120px'; wrap.append(canv);
    const config = {
        type: 'line',
        data: {
            labels: _.map(data.items, o=>o.period),
            datasets: [{ backgroundColor: '#74d2e7', borderColor: '#48a9c5', data: _.map(data.items, o=>o.value), }],
        },
        options: {
            scales: { x: { display: false, } },
            plugins: {
                title: {
                    display: true,
                    text(context) {
                        if(data.rval) {
                            return '검색어 트렌드 (실 검색량)';
                        } else {
                            return '검색어 트렌드';
                        }
                    }
                },
                legend: { display: false },
                tooltip: {
                    callbacks: {
                        label(context) {
                            if(data.rval) {
                                return `${format_number(context.parsed.y.toFixed(0))}회 검색 됨`
                            } else {
                                return `${format_number(context.parsed.y.toFixed(2))}%`
                            }
                        }
                    }
                }
            },
        }
    };
    const chart = new Chart(canv, config);
}
function _requestIdleCallback(callback) {
    if(typeof requestIdleCallback == 'undefined') return setTimeout(callback, 1000);
    return requestIdleCallback(callback);
}
function checkForDOM() { return (document.body) ? main() : _requestIdleCallback(checkForDOM); }
_requestIdleCallback(checkForDOM);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址