imdbサイトのデータから、2018年おすすめの映画・ドラマを探し出す。
import re
import numpy as np
from time import sleep
from time import time
from random import randint
from requests import get
from bs4 import BeautifulSoup
from IPython.core.display import clear_output
# ループ監視の準備
start_time = time()
requests = 0
pages = [str(i) for i in range(1,2002,50)]
headers = {"Accept-Language": "en-US, en;q=0.5"}
movieTitle = []
movieDate = []
movieRunTime = []
movieGenre = []
movieRating = []
movieScore = []
movieDescription = []
movieDirector = []
movieStars = []
movieVotes = []
movieGross = []
for page in pages:
# get requestをする
response = get('https://www.imdb.com/search/title/?release_date=2019-01-01,2019-12-31&sort=num_votes,desc&start=' + page +
'&ref_=adv_nxt', headers = headers, proxies = proxies)
# ループをポーズする
sleep(randint(8,15))
# requestsをモニターする
requests += 1
elapsed_time = time() - start_time
print('Request:{}; Frequency: {} requests/s'.format(requests, requests/elapsed_time))
clear_output(wait = True)
# non-200 status codesに対して警告する
if response.status_code != 200:
warn('Request: {}; Status code: {}'.format(requests, response.status_code))
# 下記の数字以上になったらブレークする
if requests > 41:
warn('Number of requests was greater than expected.')
break
# BeautifulSoupでrequestの内容をパースする
page_html = BeautifulSoup(response.text, 'html.parser')
# 単ページの全50作品を選択する
mv_containers = page_html.find_all('div', class_ = 'lister-item mode-advanced')
for movie in mv_containers:
movieFirstLine = movie.find("h3", class_="lister-item-header")
movieTitle.append(movieFirstLine.find("a").text)
movieDate.append(re.sub(r"[()]","", movieFirstLine.find_all("span")[-1].text))
try:
movieRunTime.append(movie.find("span", class_="runtime").text[:-4])
except:
movieRunTime.append(np.nan)
movieGenre.append(movie.find("span", class_="genre").text.rstrip().replace("\n","").split(","))
try:
movieRating.append(movie.find("strong").text)
except:
movieRating.append(np.nan)
try:
movieScore.append(movie.find("span", class_="metascore").text.rstrip())
except:
movieScore.append(np.nan)
movieDescription.append(movie.find_all("p", class_="text-muted")[-1].text.lstrip())
movieCast = movie.find("p", class_="")
try:
casts = movieCast.text.replace("\n","").split('|')
casts = [x.strip() for x in casts]
casts = [casts[i].replace(j, "") for i,j in enumerate(["Director:", "Stars:"])]
movieDirector.append(casts[0])
movieStars.append([x.strip() for x in casts[1].split(",")])
except:
casts = movieCast.text.replace("\n","").strip()
movieDirector.append(np.nan)
movieStars.append([x.strip() for x in casts.split(",")])
movieNumbers = movie.find_all("span", attrs={"name": "nv"})
if len(movieNumbers) == 2:
movieVotes.append(movieNumbers[0].text)
movieGross.append(movieNumbers[1].text)
elif len(movieNumbers) == 1:
movieVotes.append(movieNumbers[0].text)
movieGross.append(np.nan)
else:
movieVotes.append(np.nan)
movieGross.append(np.nan)
movieData = [movieTitle, movieDate, movieRunTime, movieGenre, movieRating, movieScore, movieDescription,
movieDirector, movieStars, movieVotes, movieGross]
import pandas as pd
df = pd.DataFrame(movieData).T
df.tail()
df.columns = ['タイトル','公開年','上映時間','ジャンル','IMDBスコア','メタスコア',\
'あらすじ','監督','出演者','投票数','興行収入']
print(df.info())
df.sort_values(by='IMDBスコア',ascending=False).head(10)
「Attack on Titan」って何や?と思って調べてみると、「進撃の巨人」とかいうアニメのことだった。投票数が少ないとimdbスコアもあまり当てにならないようである。投票数を一定数以上に設定する必要がありそうだ。
df['投票数'] = df['投票数'].str.replace(',','')
df['投票数'] = df['投票数'].apply(pd.to_numeric, errors="coerce").astype(int)
df1 = df[(df['投票数'] > 1e4)]
df1.sort_values(by='IMDBスコア',ascending=False).head(10)
「Chernobyl」がメチャメチャ高評価であることが伺える。チェルノブイリはHBO制作のドラマミニシリーズだそうだ。正確には、HBOとSky UKの共同制作となっている。日本のどっかのテレビ局も「Fukushima」というドラマミニシリーズを作ってみてはどうだろうか。今度は投票数を5万以上に設定してみる。
df2 = df[(df['投票数'] > 5e4)]
df2.sort_values(by='IMDBスコア',ascending=False).head(10)
Love, Death & Robots, Sex Education, The Umbrella AcademyはNetflixオリジナル作品となっている。Game of ThronesはChernobyl同様HBOオリジナルで、日本でも有名な海外ドラマである。アベンジャーズ/エンドゲームは日本では低人気であるが、世界的にはメガヒットしている。ジョン・ウィック パラベラムは、日本で大人気のキアヌ・リーブス主演のアクション映画、日本公開は10月となっている。既に4の制作も決まっているとか。今度はメタスコア最高値を検出する。
df.sort_values(by='メタスコア',ascending=False).head(10)
Portrait of a Lady on Fireは、セリーヌ・シアマ監督のカンヌ国際映画祭脚本賞を授賞したフランス映画である。このタイトルのあらすじを見てみる。
df['あらすじ'][1517]
あらすじは、「18世紀末、1人の女性画家が、ブリタニーの孤島で若い女性の婚礼肖像画を描くことになっている。」という興味深い内容である。フランス公開は9月18日で、日本で公開されるかどうかは未定である。「Parasite」は韓国映画で、韓国映画初となるパルムドールをカンヌ国際映画祭で受賞している。この映画は日本公開が決まっているようである。あらすじを見てみる。
df['あらすじ'][216]
あらすじは、一家全員が失業中のKi-taek家が、一家が予期せぬ事態に巻き込まれるまで、裕福でグラマラスなPark家の生活に特別な興味を抱くようになる。となっており、パラサイトというタイトルから何となく話の内容が見えてくるような気もするが、一度見てみたい作品ではある。「Once Upon a Time … in Hollywood」は日本でもお馴染みのタランティーノ監督、ブラピやディカプリオが共演するので、公開が待ち遠しい作品ではないだろうか。この映画のあらすじを見てみる。
df['あらすじ'][135]
あらすじは、落ち目のTV俳優とそのスタントダブルが、1969年のロスアンジェルスで、ハリウッド黄金期末期の映画界で、名声と成功を勝ち取ろうと悪戦苦闘する。となっているが、wikiでは、「1969年にハリウッド女優シャロン・テートがカルト集団チャールズ・マンソン・ファミリーに殺害された事件を背景に、ハリウッド映画界を描いた作品。」となっている。