Togetterの内容をGoogleChromeの検証機能でスクレイピングし、WordCloudで可視化してみる

会社での一山越えたのですが、まだまだいろいろと作業があるので微妙なところです。

【イベントページ】

www.ctv.co.jp

さてその山となったイベントがTogetterのまとめページにまとめられたので、今回のエントリーではそのまとめページスクレイピングして、 Wordcloudで処理してみようと考えました。簡単に考えてTogetterのデータはTitter経由で書き込まれているので、以前行ったのと同様に Twitterの書き込みを取得すればいいかなと思ったのですが、同じことをしても面白くないなと思ったのでTogetterのWebサイトをスクレイピングして データの取得を行おうと思います。

【Togetterのまとめページ

togetter.com

WordCloudに関しては下記のエントリーを参考にすればできるかと思います。

【関連】 uepon.hatenadiary.com

Togetterからのスクレイピング処理

基本的にはhttps://togetter.com/li/というURLの末尾にIDをつけることでそれぞれのまとめページに飛ぶことができるようになっています。 今回のターゲットのURIhttps://togetter.com/li/1317653となります。

WebのスクレイピングなのでpythonRequestsモジュールとBeautifulSoup4モジュールを使用して取得したあとにHTMLの解析を行うという形が一般的ですが、 今回は別の方法としてGoogle Chromeの検証機能を使用してスクレイピングを行うことにしました。これだとほとんどコードを書く必要がないのも魅力です。 ただページごとに取得処理を行う必要がある点は面倒ですが…。

【参考】

luuluuul.com

ページを右クリックして表示されるメニューの一番下にある【検証】を選択すると

f:id:ueponx:20190217230549p:plain

検証ツールがWindow内に表示されます。

f:id:ueponx:20190217231359p:plain

その中の【Elements】のタブのHTMLのDOMのツリー構造からTwitterの書き込み部分のものを探していきます。

f:id:ueponx:20190217233342p:plain

該当する部分が見つかったら【console】のタブに移動して出力をさせていきます。ツリー上の要素を表示させるには

$$("【CSSセレクタ】")

とすれば要素の表示が行われます。bodyタグの内容を表示させる場合には

$$("body")

とすればOKです。

f:id:ueponx:20190217233418p:plain

この仕組みを使用すれば、あとはループ処理を使うことで書き込みの文書をすべて取得することができます。 TogetterのTitterでの書き込みの本文だけを取得する場合には以下のようなスクリプトをコンソール上にコピーペーストすれば 出力をクリップボード上にコピーすることができます。

var result = "";
for (var i = 0; i < $$("div.tweet_box div.list_box.type_tweet div.tweet").length; i++) {
    result += $$("div.tweet_box div.list_box.type_tweet  div.tweet")[i].innerText + "\r";
}
//console.log(result);

//クリップボードにコピー
var ta = document.createElement('textarea');
ta.value = result;
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
ta.parentElement.removeChild(ta);

f:id:ueponx:20190217233549p:plain

このスクリプトの実行を行うと以下のようなデータが取得されます。(クリップボードにコピーされます。)

【hackchu2019_log.txt】

IBMは〇〇テレビハッカソン【HACK-CHU! 2019】を応援します
今週末土曜日は予選【アイデアソン】天気予報では雪マークが出ているようなので当日まで体調を整えて挑みましょう!
ctv.co.jp/hackathon2019/
#hackchu #中京テレビ #IBM #TryIBMDev pic.twitter.com/92WKLrA1Ip
都内は雪が降ってきました
今日は長い一日になりそうです。
#hackchu pic.twitter.com/GFhUn3lelJ
今日は〇〇テレビ主催のハッカソン「Hack-Chu(読み方:ハックチュウ)」のスポンサーメンターとして参加します。昨年の写真見てるとみんな良い笑顔でいらっしゃる今年はどんな感じになるか楽しみです
…(以下略)…

複数ページにまたがる場合にはこれをページ数ごとに行うことでまとめられたすべてを取得できます。

WordCloudでの処理

あとは文面を取得できたのでこれをWordCloudで処理させていけばOKです。 必要であれば以下のパッケージを事前にインストールしておいてください。

(venv) >pip install wordcloud
(venv) >pip install matplotlib
(venv) >pip install janome

WordCloudの事前処理

WordCloudで処理する前にJanome形態素解析を行います。 形態素解析をそのままやってしまうとノイズの多いデータになってしまうので、できるだけここでいらない語句は省くのがいい結果を得られるコツだと思います。

形態素解析の処理】

from janome.tokenizer import Tokenizer
import codecs

wakachi = ''

with codecs.open('./wakachi_log.txt', mode='w', encoding='utf-8') as fw:
    None

t = Tokenizer()
with open('hackchu2019_log.txt', 'r', encoding="utf-8") as f:
    for tweet in f:
        if tweet.startswith('#'):
            continue
        tweet = tweet.split('pic.twitter.com')[0].strip()
        tweet = tweet.split('ctv.co.jp')[0].strip()
        tweet = tweet.replace('#hackchu', '')
        # print(tweet)
        word_list = []
        tokens = t.tokenize(tweet)
        for token in tokens:
            word = token.surface
            word_base = token.base_form
            partOfSpeech = token.part_of_speech.split(',')[0]
            if token.base_form in ["ある", "なる", "こと", "よう", "そう",
                                   "これ", "それ", "する", "いる", "いい",
                                   "やる", "わかる","自分", "こちら","いう","サービス",
                                   "くる","いう","かける","行く","やつ","中京",
                                   "使える", "来る","ない","ww", "思う", "ハッカソン","予選",
                                   "見る", "持つ", "〇〇TV","チーム","TV"]:
                continue
            if partOfSpeech in ["形容詞", "動詞", "名詞", "代名詞", "副詞"]:
                if (partOfSpeech == "名詞"):
                    if (token.part_of_speech.split(',')[1] in ["数", "接尾", "助数詞", "非自立"]):
                        continue
                elif (partOfSpeech == "動詞"):
                    if (token.part_of_speech.split(',')[1] not in ["自立"]):
                        continue
                elif (partOfSpeech == "形容詞"):
                    if (token.part_of_speech.split(',')[1] not in ["自立"]):
                        continue
                elif (partOfSpeech == "副詞"):
                    if (token.part_of_speech.split(',')[1] in ["助詞類接続"]):
                        continue
                word_list.append(word_base)

        wakachi = " ".join(word_list)
        with codecs.open('./wakachi_log.txt', mode='a', encoding='utf-8') as fw:
            print(wakachi, file=fw)

この処理で以下のような形態素解析後の分かち書きされたテキストデータを得ることができます。

【wakachi_log.txt】

IBM テレビハッカソン HACK - CHU ! 応援
今週 土曜日 アイデアソン 天気 予報 雪 マーク 出る 当日 体調 整える 挑む
都内 雪 降る
今日 長い
今日 テレビ 主催 Hack - Chu ( 読み方 : ハックチュウ )」 スポンサーメンター 参加 昨年 写真 みんな 良い 笑顔 いらっしゃる 今年 感じ 楽しみ
テレビハッカソン HACK - CHU !」
…(以下略)…

あとはこの出力をWordCloudで処理させるだけです。

WordCloudでの処理

あとは、WordCloudで処理するだけです。 以下のコードで日本語のフォント指定をすれば無事に処理されます。

import os
from wordcloud import WordCloud
contents = open('wakachi_log.txt', encoding="utf-8").read()
fpath = 'C:\\Windows\\Fonts\\meiryo.ttc'
wordcloud = WordCloud(background_color="white", font_path=fpath, width=900, height=500).generate(contents)
wordcloud.to_file("./wordcloud.png")

処理後に以下のような画像データが表示されます。

f:id:ueponx:20190217022855p:plain

無事にデータが取得できました。

終わりに

Pythonを使ってスクレイピングするのもいいですが、Javascriptなどを実行しないと行けないような場合は単純な処理ではだめですが、 Google Chromeの検証機能を使えばあまり気にせずにスクレイピングを行い、該当のデータを取得することはできそうです。 どちらが手間かを考えて取捨選択していけばいいかなとは思いました。