以可视化方式回顾一年来的Google搜索关键词
这是Hamee Advent Calendar的第二天文章。
我计划将我们通常轻而易举地使用的Google搜索关键字历史可视化,并尝试分析自己过去对什么感兴趣。
整个流程
-
- 下载搜索历史记录
-
- 提取搜索关键词
-
- 引入Kibana+Elasticsearch
-
- 将数据导入Elasticsearch
- 可视化
目录结构
这是最终的目录结构。
.
├── data
│ ├── bulk_insert.json
│ ├── bulk_insert.rb
│ ├── index.html
│ ├── parse.rb
│ ├── search_keywords.json
│ └── 検索
│ ├── 2017-01-01 2017年1月〜2017年3月.json
│ ├── 2017-04-01 2017年4月〜2017年6月.json
│ ├── 2017-07-01 2017年7月〜2017年9月.json
│ └── 2017-10-01 2017年10月〜2017年12月.json
├── docker-compose.yml
└── elasticsearch
└── Dockerfile
下载搜索历史记录
毫无疑问,没有数据就无从开始,所以我会下载谷歌的搜索历史记录。
您可以在谷歌的下载页面上选择搜索历史,然后下载一个zip格式的文件。
https://takeout.google.com/settings/takeout
解压缩下载的zip文件后,会生成以下的目录结构。
(尽管JSON文件存在于2017年之前,但由于本次仅针对2017年,故已删除。)
Takeout
├── index.html
└── 検索
├── 2017-01-01 2017年1月〜2017年3月.json
├── 2017-04-01 2017年4月〜2017年6月.json
├── 2017-07-01 2017年7月〜2017年9月.json
└── 2017-10-01 2017年10月〜2017年12月.json
查看json文件的内容
我們在這裡先來確認下載的搜尋記錄資料結構。
timestamp_usec代表了搜索时的时间,并以UNIX时间戳的纳秒表示。
query_text是实际进行搜索时的搜索字符串,我们将对这个字符串进行分解,以获取搜索关键字列表。
{
"event": [
{
"query": {
"id": [
{
"timestamp_usec": "1490981273760997"
}
],
"query_text": "秋葉原ダイビル"
}
},
{
"query": {
"id": [
{
"timestamp_usec": "1490932140812972"
}
],
"query_text": "php conference"
}
},
...
提取搜索关键词
数据结构
现在,我们将从下载的JSON文件中提取所需的数据。
我们将分解搜索字符串,并获取搜索时间和搜索关键词的组合列表。
关于搜索时间,由于使用了UNIX时间戳表示,我们将其转换为以毫秒表示的日期格式。
[
{
"timestamp": "2017-03-31 12:49:00",
"keyword": "php"
},
{
"timestamp": "2017-03-31 12:49:00",
"keyword": "conference”
},
....
]
此外,可能存在多个timestamp_usec,但在这种情况下,只是在短时间内多次执行搜索,因此我们将其视为一次起始搜索。
{"id"=>[{"timestamp_usec"=>"1508764388232195"}, {"timestamp_usec"=>"1508764390541359"}, {"timestamp_usec"=>"1508764411274548"}], "query_text"=>"docker ディレクトリ マウント build"}
获取搜索历史关键词列表
关于获取关键词列表,可以执行以下Ruby脚本,生成search_keywords.json文件。
$ ruby parse.rb
require 'json'
# Google検索履歴のJSONファイルを読み込んで、クエリ情報を配列で返す
def readQueries(json_file)
File.open(json_file) do |file|
return JSON.load(file)['event'].map{|item| item['query']}
end
end
# 複数のJSONデータを読み込んで結合する
queries = Dir.glob('検索/*.json')
.reduce([]){|array, file|
array.concat(readQueries(file))
}
search_keywords = queries.map{|query|
# 検索履歴のクエリをキーワード毎に分解
keywords = query['query_text'].split(/\s| /)
# Googleでの検索時間を取得
timestamp = query['id'][0]['timestamp_usec']
keywords.map{|keyword|
# UNIタイムスタンプを日付表記に変換する(単位はナノ秒になっているので注意)
{'timestamp'=> Time.at(timestamp.to_i / 1000000).strftime('%Y-%m-%d %H:%M:%S'), 'keyword'=> keyword}
}
}.flatten
File.write('search_keywords.json', JSON.pretty_generate(search_keywords))
在中国引入Kibana+Elasticsearch
接下来,我们将引入Kibana+Elasticsearch作为可视化搜索历史关键词的工具。由于对Kibana和Elasticsearch的说明会变得较长,所以我们将省略。
这次我们将使用Docker来快速引入。
.
├── data
│ ├── index.html
│ ├── parse.rb
│ ├── search_keywords.json
│ └── 検索
│ ├── 2017-01-01 2017年1月〜2017年3月.json
│ ├── 2017-04-01 2017年4月〜2017年6月.json
│ ├── 2017-07-01 2017年7月〜2017年9月.json
│ └── 2017-10-01 2017年10月〜2017年12月.json
├── docker-compose.yml
└── elasticsearch
└── Dockerfile
docker-compose.yml 可以被重新改写成:
version: '2'
services:
elasticsearch:
build: ./elasticsearch
volumes:
- es-data:/usr/share/elasticsearch/data
ports:
- 9200:9200
expose:
- 9300
ulimits:
nofile:
soft: 65536
hard: 65536
# https://github.com/docker-library/elasticsearch/issues/111
# uliimit
kibana:
image: kibana:5.3
links:
- elasticsearch:elasticsearch
ports:
- 5601:5601
volumes:
es-data:
driver: local
elasticsearch/Dockerfile 的中文释义:弹性搜索/容器文件。
FROM elasticsearch:5.3
# kuromojiをインストール
RUN elasticsearch-plugin install analysis-kuromoji
创建容器
请访问 http://127.0.0.1:5601,如果能够显示Kibana界面,说明安装已完成。
$ docker-compose up -d
将数据投入Elasticsearch
为了在Kibana上可视化提取出的关键词列表,将其输入到Elasticsearch中。
创建映射
首先,在Elasticsearch中创建映射。
$ curl -XPUT 'http://localhost:9200/google_search_history' -d '{
"mappings": {
"keywords": {
"properties": {
"timestamp": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"keyword": {
"type": "keyword"
}
}
}
}
}'
创建注册数据
为了将数据批量注册到Elasticsearch中,我们将从先前生成的search_keywords.json文件中创建用于批量注册的bulk_insert.json文件。
$ ruby bulk_insert.rb
require 'json'
INDEX = 'google_search_history'
TYPE = 'keywords'
# データをインサートするJSONを生成
def insert(index, type, data)
hash = {'index' => {'_index'=>index, '_type'=>type}}
[hash, data].map{|item|
JSON.generate(item)
}.join("\n")
end
queries = File.open('search_keywords.json') do |file|
JSON.load(file)
end
# 各データを変換して、バルクインサートするためのJSONを生成
bulk_insert_json = queries.map{|query| insert(INDEX, TYPE, query)}.join("\n")
File.write('bulk_insert.json', bulk_insert_json)
数据输入 de
使用curl命令将bulk_insert.json的内容导入Elasticsearch。
$ curl -XPOST localhost:9200/google_search_history/keywords/_bulk --data-binary @bulk_insert.json > /dev/null
可视化
终于准备工作已经完成,现在让我们通过Kibana来查看关键词。
选择 index_pattern。
首先,您需要从管理部门设置索引模式。
这次我们将设置已创建的索引google_search_history。

用标签云显示
根据2月份的搜索次数,我们将使用标签云来显示搜索关键词。
看到elixir的搜索次数相当多,不是吗?
PS4的搜索次数很多,我想可能是考虑购买的人比较多。(部分我留给你猜测。)

以圆形图表示
我们来通过饼图查看整体比例。
通过饼图可以看出,Elixir的搜索次数明显超过其他。

显示搜索趋势的时间序列。
让我们看看elixir在过去一年的搜索趋势。
从趋势来看,在前几个月的2月和3月,搜索量最集中。
正如图表所示,这个时期大家对elixir非常狂热。
然而,自那时起我就不再去搜索是否满足了。
.es(index='google_search_history', q='keyword:"elixir"', metric="count", timefield='timestamp').color(green).label(elixir)

展示每个时期的个人趋势。
最后,我会尝试将Elixir、PHP和JavaScript的搜索趋势一起总结并显示出来。
每种语言的搜索时间都各不相同,就像个人的谷歌趋势搜索一样!

最後
如果将Google搜索关键词进行可视化,就可以看到过去对什么感兴趣以及兴趣的变化等,所以结果比我想象的更令人满意。
数据可视化让我们能够看见看不见的东西,非常有趣呀。
请查阅相关资料。
ブラウザの閲覧履歴で人生の棚卸し(embulk + elasticsearch + kibanaで可視化) – Qiita
Dockerを利用して Elasticsearch + Kibana の環境を作る – Qiita