はじめに
本記事では、映画.comの「劇場版 鬼滅の刃 無限列車編」のレビューをスクレイピングし、csvで出力します。
環境
python 3.10.4
Windows 11 Home
ChromeDriver 114.0.5735.110
必要なライブラリのインストール
seleniumとpandasを使用します。
seleniumはブラウザの操作を自動化するライブラリですが、スクレイピングも行うことができます。今回は「次へ」ボタンの押下も自動化し、全レビューの取得を目的とするため、こちらを使用します。
pandasはデータ解析に使うライブラリです。今回はスクレイピングして取得したデータをcsvで出力する目的で使用します。
pip install selenium
pip install pandas
HTMLの構造
映画.comのレビュー部分は以下のようなHTMLで構成されています。(2023年8月現在)
<!-- このdiv要素がレビューの数だけ並ぶ -->
<div class="txt-block">
<p class="short">レビュー前半(実際に表示されている部分)
<span>…</span>
<span class="hidden" style="display: none;">レビュー後半(文字数制限で表示できていない部分)</span>
<a class="more">続きを読む</a>
</p>
</div>
<!-- 次へボタンが押せる場合 -->
<a class="next icon-after" href="url">次へ</a>
<!-- 次へボタンが押せない場合 -->
<span class="next disabled icon-after">次へ</span>
作成コード
上記のHTML要素を取得し、スクレイピングを行います。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pandas as pd
import time
# ブラウザの起動
chromedriver = "chromedriver.exe"
service = Service(execureviews_path=chromedriver)
driver = webdriver.Chrome(service=service)
url = "https://eiga.com/movie/91918/review/"
driver.get(url)
# データを取得し、配列に格納する
reviews = []
is_continue = True
while(is_continue):
text_elems = driver.find_elements(By.CLASS_NAME, "txt-block")
for text_i in text_elems:
text = text_i.get_attribute("textContent")
if '続きを読む' in text:
text = text.replace("…","").replace("続きを読む","")
if 'ネタバレ! クリックして本文を読む' in text:
text = text.replace("ネタバレ! クリックして本文を読む","")
# 配列にデータを格納
reviews.append(text)
# 次へボタンが押せなければループを終了、押せるなら押して次のページへ
if driver.find_elements(By.CSS_SELECTOR, ".next.icon-after.disabled"):
is_continue = False
else:
next_button = driver.find_element(By.CSS_SELECTOR, ".next.icon-after")
next_button.click()
time.sleep(2)
# 配列からDataFrameを作成し、csvで出力する
df = pd.DataFrame(reviews, columns=['レビュー'])
df.index.name = 'index'
df.to_csv("無限列車編_レビュー.csv", encoding="utf-8")
#ブラウザの終了
driver.quit()
解説
text_elems = driver.find_elements(By.CLASS_NAME, "txt-block")
for text_i in text_elems:
text = text_i.get_attribute("textContent")
if '続きを読む' in text:
text = text.replace("…","").replace("続きを読む","")
if 'ネタバレ! クリックして本文を読む' in text:
text = text.replace("ネタバレ! クリックして本文を読む","")
-
driver.find_elements(By.CLASS_NAME, 'txt-block')
クラス名が「txt-block」である要素を全て取得 -
text_i.get_attribute("textContent")
クラス名「txt-block」を持つタグが内部に持っている全文字列を連結して取得 -
replace("…","")
文字列中に含まれる「…」を削除する
text_i.text
とすると、display: none
指定されているレビュー後半部分を取得することができませんでした。そのため、text_i.get_attribute("textContent")
で、display: none
指定されている部分を含めた全文字列を取得し、その後、不要な文字列をreplace
で取り除いています。
if driver.find_elements(By.CSS_SELECTOR, ".next.icon-after.disabled"):
is_continue = False
else:
next_button = driver.find_element(By.CSS_SELECTOR, ".next.icon-after")
next_button.click()
time.sleep(2)
-
driver.find_elements(By.CSS_SELECTOR, ".next.icon-after.disabled")
クラス名「next」、「icon-after」、「disabled」を持つ要素(押せない次へボタン)を取得 -
time.sleep(2)
2秒間待機
押せない次へボタンがある場合はデータ取得処理を終了し、ない場合は次へボタンを押して次のページに進みます。
2秒間待機を挟むのは、ページが読み込まれる前に要素の検索が実行され、エラーとなるのを防ぐためです。
終わりに
今回は映画.comのレビューをスクレイピングしました。
ボタンを押したら文字を表示する仕組みは、他のwebサイトでも活用されているので、.get_attribute("textContent")
は応用が利きそうと感じました。
今後は取得したcsvを使ってテキストマイニングを行う予定です。