突然ですが、『咲-Saki-』の登場人物リストのデータファイルを作りたくなりました。
データの参照元としては、もちろん作者の小林立先生の公式サイトの『咲-Saki- キャラクター一覧』が筆頭に挙げられます。そして比較のためにWikipediaの咲-Saki-の登場人物からもデータを取る方針にします。
お手軽に作りたかったので、サクッとプログラムを組んでみました。
『咲-Saki-』の登場人物のリストをWebから取得するプログラム
プログラムにはPythonを使いました。あらかじめ、下記のモジュールをインポートしておきます。
- URLを解釈するための、urllib.parse
- URLからHTMLを取得するための、requests
- 取得したHTMLを解釈するための、Beautiful Soup
- データを整理するための、pandas
後は、サックリと。
####################################################### # SakiNameCollector.py # # 機能:『咲-Saki-』の登場人物のリストを作る # # 履歴:Rev.1.00: 2020/05/24 新規作成 # # 2020 USO9000 All rights reserved. # ####################################################### import re import urllib.parse import requests, bs4 import pandas as pd #小林立先生のサイトからキャラクター名を取得 def GetSciasta(): #DFを作成 lst_coloumn = ['姓', '名', '読み1', '読み2', '所属', '学年', '誕生日', '身長'] df = pd.DataFrame(columns = lst_coloumn) #立先生のサイトからページデータをダウンロード url = 'http://sciasta.com/characters.html' res = requests.get(url) #解析&キャラクター名取得 if (res.status_code == requests.codes.ok): #ページデータをBeautiful Soupに入れて解析準備 page = bs4.BeautifulSoup(res.content, 'lxml') #キャラクターデータを抽出 for tr in page.select('tr'): #<tr>の要素を抽出 offs = 0 td_list = tr.select('td') #<td>の要素を抽出 if len(td_list) != 0: for td in td_list: #<td>の要素を抽出 name = td.getText() #名前のテキスト部分を抽出 if offs == 0: m = re.search(r'.*?\s', name) #姓を正規表現で検索 if bool(m): #姓名が分かれている場合 sei = name[m.start():m.end()-1] m = re.search(r'\s.+', name) #名を正規表現で検索 mei = name[m.start()+1:m.end()] else: #姓名が分かれていない場合 sei = name mei = '' elif offs == 1: m = re.search(r'.*?\s', name) #姓の読みを正規表現で検索 if bool(m): #姓名が分かれている場合 yomi1 = name[m.start():m.end()-1] m = re.search(r'\s.+', name) #名の読みを正規表現で検索 yomi2 = name[m.start()+1:m.end()] elif '・' in name: #外国人の場合 m = re.search(r'.*?・', name) #姓の読みを正規表現で検索 yomi1 = name[m.start():m.end()-1] m = re.search(r'・.+', name) #名の読みを正規表現で検索 yomi2 = name[m.start()+1:m.end()] else: #姓名が分かれていない場合 yomi1 = name yomi2 = '' elif offs == 2: m = re.search(r'.年', name) #所属を正規表現で検索 if bool(m): #学年がある場合 group = name[:m.start()] #職業 school_year = name[m.start():m.end()] #学年 elif '阿知賀女子中' in name: #例外処理 m = re.search(r'阿知賀女子中', name) group = name[m.start():m.end()] school_year = name[m.end():] + '年' #学年 else: #学年がない場合 group = name #職業 school_year = '' elif offs == 3: birthday = name #誕生日 elif offs == 4: height = name #身長 offs = offs + 1 else: print('fail') return df #Wikipediaからキャラクター名を取得 def GetWikipedia(): #DFを作成 lst_coloumn = ['姓', '名', '読み1', '読み2', '所属'] df = pd.DataFrame(columns = lst_coloumn) #Wikipediaからページデータをダウンロード url_post = 'https://ja.wikipedia.org/wiki/' url = url_post + urllib.parse.quote('咲-Saki-の登場人物') res = requests.get(url) #解析&キャラクター名取得 if (res.status_code == requests.codes.ok): #ページデータをBeautiful Soupに入れて解析準備 page = bs4.BeautifulSoup(res.content, 'lxml') #キャラクター名,団体名を抽出 tag_list = page.find_all(class_=['anchor','mw-headline']) #class="anchor"と"mw-headline"の要素を抽出 for tag in tag_list: if 'mw-headline' in str(tag): #所属部分抽出 group = tag.getText() #所属のテキスト部分を抽出 if ('校' not in group) and ('院' not in group) and ('園' not in group) and ('女子' not in group) or ('その他' in group): #例外処理1 group = '' if '・' in group: #例外処理2 group = group[group.find('・')+1:] if 'anchor' in str(tag): #名前部分抽出 name = tag.getText() #名前のテキスト部分を抽出 if ' ' in name: #姓名が分かれている場合 m = re.search(r'.*?\s', name) #姓を正規表現で検索 sei = name[m.start():m.end()-1] m = re.search(r'\s.+?(', name) #名を正規表現で検索 mei = name[m.start()+1:m.end()-1] m = re.search(r'(.+?\s', name) #姓の読みを正規表現で検索 yomi1 = name[m.start()+1:m.end()-1] m = re.search(r'\s\S+?)', name) #名の読みを正規表現で検索 yomi2 = name[m.start()+1:m.end()-1] elif '・' in name: #外国人の場合 m = re.search(r'.*?・', name) #姓を正規表現で検索 sei = name[m.start():m.end()-1] m = re.search(r'・.+', name) #名を正規表現で検索 mei = name[m.start()+1:m.end()] yomi1 = '' yomi2 = '' else: #姓名が別れが分かれていない場合 sei = name mei = '' yomi1 = '' yomi2 = '' new_coloumn = pd.DataFrame(data=[[sei, mei, yomi1, yomi2, group]], columns = lst_coloumn) df = df.append(new_coloumn, ignore_index=True) else: print('fail') return df #キャラクター名リストを比較チェック def CheckNameList(df1, df2): #DFを作成 lst_coloumn = ['姓', '名', '読み1', '読み2', '所属'] df_add = pd.DataFrame(columns = lst_coloumn) print('小林立先生の収録:{}名'.format(len(df1))) print(' Wikipediaの収録:{}名'.format(len(df2))) print('') #立先生のサイトをWikipediaと比較 print('立先生のサイトにあってWikipediaにないキャラ') sciasta_count = 0 for row1 in df1.itertuples(): wiki_flag = 0 for row2 in df2.itertuples(): if (((row1.姓 == row2.姓) and (row1.名 == row2.名)) or ((row1.読み1 == row2.姓) and (row1.読み2 == row2.名))): wiki_flag = 1 break if (wiki_flag != 1): print(' ' + row1.姓 + ' ' + row1.名) sciasta_count = sciasta_count + 1 print('合計:{}名'.format(sciasta_count)) print('') #Wikipediaを小林立先生のサイトと比較 print('Wikipediaにあって立先生のサイトにないキャラ') wiki_count = 0 for row2 in df2.itertuples(): sciasta_flag = 0 for row1 in df1.itertuples(): if (((row1.姓 == row2.姓) and (row1.名 == row2.名)) or ((row1.読み1 == row2.姓) and (row1.読み2 == row2.名))): sciasta_flag = 1 break if (sciasta_flag != 1): print(' ' + row2.姓 + ' ' + row2.名) wiki_count = wiki_count + 1 new_coloumn = pd.DataFrame(data=[[row2.姓, row2.名, row2.読み1, row2.読み2, row2.所属]], columns = lst_coloumn) df_add = df_add.append(new_coloumn, ignore_index=True) print('合計:{}名'.format(wiki_count)) df1 = pd.concat([df1, df_add]) df1 = df1.reset_index(drop=True) return df1 if __name__ == '__main__': #小林立先生のサイトからキャラクター名を取得 df1 = GetSciasta() #Wikipediaからキャラクター名を取得 df2 = GetWikipedia() #結合してCSVファイルに出力 df1 = CheckNameList(df1, df2) df1.to_csv('namelist.csv', encoding='utf_8_sig')
※このプログラムはフリーウェアです。個人的利用の限りにおいて利用,複製,改変は自由です。
出来た登場人物のリストを見てみる
上記のプログラムを実行して出力されたCSVファイルを表にすると、2020年5月30日現在こんな感じ↓になります。
姓 | 名 | 読み1 | 読み2 | 所属 | 学年 | 誕生日 | 身長 | |
---|---|---|---|---|---|---|---|---|
0 | 宮永 | 咲 | みやなが | さき | 清澄高校 | 1年 | 10/27 | 155 |
1 | 原村 | 和 | はらむら | のどか | 清澄高校 | 1年 | 10/04 | 154 |
… | … | … | … | … | … | … | … | … |
154 | 宮永 | 界 | みやなが | かい | 宮永家の父 | 06/10 | 175 | |
155 | 原村 | 恵 | はらむら | けい | 原村家の父 | 08/29 | 183 | |
156 | 宮永 | 愛 | みやなが | あい | ||||
157 | 原村 | 嘉帆 | はらむら | かほ | ||||
158 | 白築 | 慕 | しらつき | しの | ||||
159 | 石飛 | 閑無 | いしとび | かんな | ||||
… | … | … | … | … | … | … | … | … |
201 | 瑞原 | 美月 | みずはら | みつき | ||||
202 | 杏果の母 | |||||||
203 | ニーマン |
No.156以降がWikipediaからのデータになります。Wikipediaからの誕生日の取得は面倒だったので出来ていませんが、立先生のサイトに載ってない登場人物で誕生日が判明しているのは白築慕,白築耕介,石飛閑無,稲村杏果の4人だけなので、必要な方は手で追記してもらっても大した手間ではありません。なぜこの4人だけ誕生日が判明しているのかというと、『シノハユ』勢としては珍しく立先生の公式サイトで発表されている(発表時点では瑞原はやり含む5人分)からなのですね。当然ですが、創造主からの発表が無いと分からない世界なのであります。
そして、プログラムの実行画面の表示結果は、↓のような感じになりました。
小林立先生の収録:156名 Wikipediaの収録:197名 立先生のサイトにあってWikipediaにないキャラ 石戸 明星 十曽 湧 Alexandra Windheim 能口 彩花 伏屋 那都 多治比 真佑子 南浦 聡 合計:7名 Wikipediaにあって立先生のサイトにないキャラ 宮永 愛 原村 嘉帆 白築 慕 石飛 閑無 (-中略-) 杏果の母 ニーマン 合計:48名
公式サイトに156名も収録されていることに、あらためて驚かされます。しかも全員が誕生日と身長のデータ付き! 「設定大魔神」の異名で知られる(?)小林立先生ですが、そのご尽力には頭が下がります。
Wikipediaと比べてみると、先に書いたように『シノハユ』のみに登場するキャラクターが、公式サイトでは収録されていません。これは『シノハユ』以降スピンアウトが増えて手が回らないのか、あるいは成長期の物語のため身長が載せられないからなのか、作者のみぞ知るですね。
まだ公式サイトに収録されていない重要人物は、宮永愛(旧姓:愛・アークタンデ)と 原村嘉帆というママさんコンビですが、これは登場時期が新しいため、まだ収録されていないということなのでしょう。
また、一方のWikipediaですが、臨海女子監督のアレクサンドラ・ヴィントハイムが収録されてないのが意外な感じでした。(気づいたら自分で書き加えろというツッコミは置いといて)
以上、「『咲-Saki-』の登場人物リスト出来るかな?」コーナーでした。