1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Filmarksからのデータ抽出を目的としたウェブスクレイピングの勉強 #5

Last updated at Posted at 2019-10-20

閑話休題として,特定の映画のレビューを全件取得し,頻出の単語の集計を行います.
ほとんど,コピペと今までのコードの流用です.
本稿は筆者の趣味の塊ですので,ご容赦ください.

#レビュー取得のコード

特定の映画のレビューを1ページ分取得するコードを紹介します.申し訳ありませんが,引用元以上のコードをかける自信がなかったので9割9分コピペです.

def fetch_movie_reviews_per_page(beautiful_soup_object):
    """
    Fetch movie reviews per page. Max 10 reviews.
    :param beautiful_soup_object:
    :return list of dict:
    """
    output = []
    # 辞書型で格納
    review = dict(review_id="",
                  review_text="",
                  posted_date="",
                  rating_score=0)

    soup = beautiful_soup_object

    # id_urlsのリストを取得(ここを変更しました)
    review_idurls = soup.select(".c-media__content > .c-media__text > a")
    # レビューのリストを取得
    review_texts = soup.select(".p-mark__review")
    # 投稿日時のリストを取得
    posted_dates = soup.select(".c-media__content > time")
    # 評価(星)のリストを取得
    rating_scores = soup.select(".c-media__content > div > .c-rating__score")
    # レビューがあれば
    if review_texts:
        # id_urls,レビュー,投稿日時,評価を各々のリストから1ずつ処理
        for review_idurl,review_text, posted_date, rating_score in zip(review_idurls,review_texts,posted_dates, rating_scores):
            # id_urlsを取得(ここを変更しました)
            review_id = review_idurl.attrs['href'].split('/')[-1]
            # レビューを取得
            review_text = review_text.text.replace("\u3000", "")
            # 投稿日時を取得
            posted_date = posted_date.get("datetime")
            # 評価無しでは0
            if rating_score.text == "-":
                review['rating_score'] = 0
            # 文字列から数値へ
            else:
                rating_score = float(rating_score.text)
                review['rating_score'] = rating_score
            review['review_id']   = review_id
            review['review_text'] = review_text
            review['posted_date'] = posted_date
            output.append(review.copy()) # output.append(review)ではすべての要素が同じになるダメ
    return output
出力結果

#頻出単語の集計

今回はMecabで形態素解析を行い,一般名詞に限り頻出単語を集計してみようと思います.
形態素解析は文章を名詞,形容詞等の品詞ごとに分割することで,Mecabはpythonと連携できる形態素解析のオープンソースです.他にjanome,jumanなどがありますが,Mecabが簡単でしたのでしようしました.
Mecabの名前の由来は,開発者の好物が「海藻のメカブだった」ことだそうです.
コードは以下の通りです.

import MeCab
import sys
import re
from collections import Counter
import pandas as pd

# レビューはcsvで出力したので読み込む
df = pd.read_csv('joker_reviews.csv')

# 形態素解析の準備
m = MeCab.Tagger()

items = []
# 1行ずつ解析
for i in range(len(df)):
    # 形態素解析
    parse = m.parse (df.review_text[i])
    # 形態素解析の結果を改行で区切ってリスト化
    lines = parse.split('\n')
    
    # 形態素解析の結果を再整理
    for line in lines:
        # リストの要素を\t・,で区切る
        mecab = re.split('[\t,]',line)
        items.append(mecab)
        
# 形態素解析の結果の内を名詞抽出
# 一般名詞をcount
words = [[item[0],1]
         for item in items
         # 名詞をリストに格納
         if (item[0] not in ('EOS', '', 't', '','') and
             (item[1] == '名詞') and (item[2] == '一般'))]

word_df = pd.DataFrame(words,columns=['一般名詞','count'])

# '一般名詞'ごとに頻度計算
out_df = word_df.groupby(['一般名詞']).sum().reset_index()

頻出単語の集計が終わりましたので,上記の出力結果の頻出単語の上位30位をグラフで示します.

# グラフ描画のためmatplotlibのpyplotをインポート
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

#最大表示列数の指定(ここでは50列を指定)
pd.set_option('display.max_columns', 50)
pd.set_option('display.max_rows', 500)

# ノートブック内で拡大・縮小可能
#%matplotlib notebook
%matplotlib inline

# seabornのスタイルでプロット
sns.set(style="darkgrid", palette="muted", color_codes=True,font=['IPAGothic'])


# 降順に並べる
rank_df = out_df.sort_values('count',ascending=False).reset_index(drop=True)

# 棒グラフを出力-x軸
labels = rank_df.iloc[:30,0].tolist()
x_axis = np.arange(len(labels))  # numpyで横軸を設定

# バーの太さ
height = 0.5

# 5月の棒グラフ
# 図の大きさ
plt.figure(figsize=(15,20))
#plt.ylim(0, 900)
y = rank_df.iloc[:30,1].to_numpy()
plt.barh(x_axis,y[::-1],height=height)
plt.yticks(x_axis,labels[::-1])# ラベル

plt.show()

出力結果

ここからのグラフを見たときの筆者の浅い感想です.
タイトルにもなっている「ジョーカー」が一番多いですね.
あとは,ジョーカーのキャライメージの「悪,狂気,笑い」や「ダーク,ナイト,ヒース」のジョーカーが登場したダークナイトのキーワードがありますね.
意外だったのが「階段」ですね.おそらく,階段でのダンスシーンのことを言ってると思いますが,上位30位に入るほど印象に残ってるとは思いませんでした.

おわりに

今回は,箸休めがてらレビューの抽出・集計を行いました.
次回は年代別で高評価の映画の抽出をします.

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?