Python

なろうAPIをPython3で使いながらAPIを使う勉強[#2]<小説家になろう>

こんにちは,しまさん(@shimasan0x00)です.

前回に引き続き小説家になろうのAPIを扱っていきたいと思います.

今回は第二回ということで条件抽出をやってみたいと思います.

環境

macOS 10.14 (Mojave)

pyenv Python3.6.7

スポンサーリンク

なろうAPI

なろうAPIについては以下のサイトで確認することができます.

サンプルプログラムはありますがもちろん?Pythonのコードはありません.

なろうAPIはHTTPでのリクエストに対してJSON形式,JSONP形式又はYAML形式,PHPのserializeで応答します.

IPアドレスごとに利用制限があるので注意が必要です.

1日の利用上限は80,000または転送量上限400MBとなっています.

スポンサーリンク

さっそくPythonでAPIを使ってみる

基本は「[https://api.syosetu.com/novelapi/api/]」に対してGETで送信します.

転送量の制限を考えgzip圧縮するパラメータを設定し,受け取ってからこちら側で処理することにします.

<コード>

import json
import requests
import gzip

url = "http://api.syosetu.com/novelapi/api/?out=json&gzip=5"

#Responce オブジェクトを生成
response = requests.get(url)

#エンコーディングを指定する
response.encoding = 'gzip'

# デコードされていないレスポンスの内容(バイト列)
r = response.content

# gzipの展開,UTF-8
res_content = gzip.decompress(r).decode("utf-8")

# JSONのデコーディング
response_json = json.loads(res_content)

print(response_json)

<出力>

[{'allcount': 623184}, {'title': '恋 と パンツ と バイオリン\u3000~あの素晴らしい調べをもう一度~', 'ncode': 'N5275FD', 'userid': 330068, 'writer': 'シャイン樽画', 'story': '\u3000中学二年の後藤・清美≪ごとう・きよみ≫は、ジュニア・オーケストラに所属するバイオリン少女。\n\u3000だが、所属しているオケ(オーケストラ)からは、\n\u3000音楽性の違いで、すっかり浮いた存在になってしまっていた……\n\u3000\n\u3000音楽や合奏を、純粋に楽しみたい清美は、\n\u3000ただプロへの通過点としてオケに所属している他のメンバーと気が合わないのだ……\n\u3000\n\u3000おまけに勘違い野郎のイケメンくん・新井和人には、\n\u3000何故だか変に気に入られ(?)何かと突っかかって来られ……\n\u3000\u3000\n\u3000そして更には……\n\u3000そんな和人にちょっかい出されている清美のことを\n\u3000和人のファンである女子メンバー達は、よく思わず……\n\u3000ついに嫌がらせが始まってしまう――\n\u3000\n 「もう限界だ……」\n\u3000\n\u3000元から気が合わないメンバーばかりのオケに辟易していた清美だが、\n\u3000その嫌がらせをきっかけに、\n\u3000ついに、オケを辞めることになり……\n\u3000\n\u3000だが……?\n\u3000\n「辞めるなんて許さねえぞ!?」\n\u3000\n\u3000清美がオケを辞めることを止めようと、\n\u3000和人は、清美に壁ドンを仕掛け、そして無理やり彼女の唇を……!?\u3000\n\u3000\n\u3000\u3000\u3000\u3000\u3000\u3000\n\n\u3000バイオリン歴20年以上の作者が送る\n\u3000バイオリンを巡る、ちょっぴり切ない青春ラブストーリー!\n\u3000ここにスタートいたします!\n\n\u3000なお、たぶん毎土日投稿の不定期連載(ヲイヲイ)', 'biggenre': 1, 'genre': 102, 'gensaku': '', 'keyword': 'R15 スクールラブ 青春 ラブコメ 残念な描写あり すれ違い バイオリン 部活動 中学生 パンツから始まる恋 悲恋(?) 腹黒メガネ 土日掲載', 'general_firstup': '2018-11-25 06:00:00', 'general_lastup': '2019-01-12 22:13:56', 'novel_type': 1, 'end': 1, 'general_all_no': 26, 'length': 83156, 'time': 167, 'isstop': 0, 'isr15': 1, 'isbl': 0, 'isgl': 0, 'iszankoku': 0, 'istensei': 0, 'istenni': 0, 'pc_or_k': 2, 'global_point': 44, 'fav_novel_cnt': 7, 'review_cnt': 0, 'all_point': 30, 'all_hyoka_cnt': 3, 'sasie_cnt': 0, 'kaiwaritu': 17, 'novelupdated_at': '2019-01-12 22:13:56', 'updated_at': '2019-01-12 22:16:18'}, 

以下20件表示される.

out=jsonで出力をJSON形式に指定しています.

gzip=5はなろうAPIで用意されているgzipによる圧縮で一番圧縮されるオプションになります.

今回は何もそれ以外に指定していないので新着更新順で20件表示されることになります.

条件抽出

今回は条件抽出パラメータを扱っていこうと思います.

詳しいものはAPIの仕様を見てみてください.

少しずつコードを動かして試していきます.

url = "http://api.syosetu.com/novelapi/api/?out=json&gzip=5"

先程の<コード>のurl部分を変えていきます.

パラメータ内容
word単語指定
文字コードはUTF-8でURLエンコード
半角または全角スペースで区切るとAND抽出
部分一致でHITします
url = "http://api.syosetu.com/novelapi/api/?out=json&gzip=5&lim=3&word=村"

<出力>

[{'allcount': 17189}, {'title': '神の無き悲しい世界', 'ncode': 'N2111FD', 'userid': 1244952, 'writer': 'arominto', 'story': 'ある日、聖域の祠に倒れている所をとある村に拾われたアキはこの村の優しき人たちにこう思った______『恩を絶対に返そう』________        だがそれは最悪の形で裏切ることになる。魔物が村を襲ったのだ。これにより偶然見つからなかったアキだけが生き残って村人は全員死亡してしまった。知らない場所、友人もいない土地で苦労しながらも大切な人を救えなかったことから町に向かい神官に道を進む。そして栄軍兵として金を稼ぐことになった。生物を殺すのだって抵抗があるし戦闘経験も皆無。だがそんな状況でもやっと見つけられた仲間と必死に働き一日の宿代をなんとか稼いできた。残念ながらこの日常も長くは続かない。ある戦闘で仲間が死亡し、アキの心は一気にどん底へ突き落とされた。でも大丈夫…今は神官だ。死んだ人を蘇生させる術も使える。そう思い蘇生の魔法を使うのだが…発動しなかった。\n…その日をきりに神は消えてしまったのだ。よって奇跡である治癒術は効果が薄くなり不遇の立場になってしまう。この出来事からアキは責任感と人を救えなかった罪悪感に苛まれる。だがそんなアキにはこの世界にきたとある使命があって……', 'biggenre': 2, 'genre': 201, 'gensaku': '', 'keyword': '残酷な描写あり ガールズラブ 異世界転生 異世界転移 日常 青春 冒険 TS 性転換 魔族 魔物 魔法 ファンタジー エルフ ドワーフ 成り上がり 不遇', 'general_firstup': '2018-11-18 13:16:00', 'general_lastup': '2019-01-13 15:00:24', 'novel_type': 1, 'end': 1, 'general_all_no': 58, 'length': 123870, 'time': 248, 'isstop': 0, 'isr15': 0, 'isbl': 0, 'isgl': 1, 'iszankoku': 1, 'istensei': 1, 'istenni': 1, 'pc_or_k': 2, 'global_point': 80, 'fav_novel_cnt': 30, 'review_cnt': 0, 'all_point': 20, 'all_hyoka_cnt': 3, 'sasie_cnt': 0, 'kaiwaritu': 44, 'novelupdated_at': '2019-01-13 15:11:28', 'updated_at': '2019-01-13 15:14:08'}]

「村」というwordが入っている小説を一つ新着更新順で取得しています.

タイトル(title),あらすじ(ex),キーワード(keyword),作者名(wname)の中に入っている場合取得されます.

個別でONにしたいときは1を指定すればいいです.

次はジャンル指定をしていきます.

パラメータ内容
biggenre大ジャンル指定
-(ハイフン)で複数選択可能
1:恋愛
2:ファンタジー
3:文芸
4:SF
99:その他
98:ノンジャンル
genre小ジャンル指定
-(ハイフン)で複数選択可能
101:異世界〔恋愛〕
102:現実世界〔恋愛〕
201:ハイファンタジー〔ファンタジー〕
202:ローファンタジー〔ファンタジー〕
301:純文学〔文芸〕
302:ヒューマンドラマ〔文芸〕
303:歴史〔文芸〕
304:推理〔文芸〕
305:ホラー〔文芸〕
306:アクション〔文芸〕
307:コメディー〔文芸〕
401:VRゲーム〔SF〕
402:宇宙〔SF〕
403:空想科学〔SF〕
404:パニック〔SF〕
9901:童話〔その他〕
9902:詩〔その他〕
9903:エッセイ〔その他〕
9904:リプレイ〔その他〕
9999:その他〔その他〕
9801:ノンジャンル〔ノンジャンル〕

大ジャンル指定の場合

url = "http://api.syosetu.com/novelapi/api/?out=json&gzip=5&lim=1&biggenre=2"
[{'allcount': 102325}, {'title': '埋没アイドルとか言われた私が転生してハーピーになってたんですけどこのまま生きてていいんでしょうか?', 'ncode': 'N2933EQ', 'userid': 1143725, 'writer': '松尾イオ', 'story': '地下アイドルとして生きてきた田中幸恵30歳。\nいい年してとか言われながらも活動してきたが、強制卒業!?\nその日にファンに刺されて死にました。\n気が付けばそこは異世界!?ていうか私に羽生えてるー!?', 'biggenre': 2, 'genre': 201, 'gensaku': '', 'keyword': 'R15 残酷な描写あり 異世界転生 異世界転移 オリジナル戦記 日常 ラブコメ ギャグ シリアス ほのぼの ダーク 女主人公 人外 中世 西洋', 'general_firstup': '2018-03-17 21:05:24', 'general_lastup': '2019-01-13 15:56:25', 'novel_type': 1, 'end': 1, 'general_all_no': 39, 'length': 80995, 'time': 162, 'isstop': 0, 'isr15': 1, 'isbl': 0, 'isgl': 0, 'iszankoku': 1, 'istensei': 1, 'istenni': 1, 'pc_or_k': 2, 'global_point': 218, 'fav_novel_cnt': 57, 'review_cnt': 0, 'all_point': 104, 'all_hyoka_cnt': 12, 'sasie_cnt': 0, 'kaiwaritu': 21, 'novelupdated_at': '2019-01-13 15:56:25', 'updated_at': '2019-01-13 16:00:06'}]

小ジャンルの場合

url = "http://api.syosetu.com/novelapi/api/?out=json&gzip=5&lim=1&genre=403"
[{'allcount': 9048}, {'title': 'ぼくの迷子記録', 'ncode': 'N8186FE', 'userid': 869561, 'writer': '西向く侍(小町)', 'story': '\u3000ただ生きるだけなら苦労しない。そんな時代に産まれた「ぼく」の話。\n\u3000福祉が進んでも、科学技術が進んでも、いつの時代でも生き方に迷う人はいると思う。\n\u3000ぼくも生き方に迷っていた。だけど、問題は切迫していない。ということだった。\n\u3000単純労働はアンドロイドが行うし、一部の重要な仕事は他の人がしている。\n\u3000ただ生きることだけが仕事。役割もなにもない「ぼく」はどう生きたものか。\n\u3000迷子みたいな毎日だった。迷子を脱却しようという物語。\n(2万文字程度に収めるつもりです)', 'biggenre': 4, 'genre': 403, 'gensaku': '', 'keyword': 'R15 近未来 人工知能 ギャグ 男主人公 西洋 未来 アンドロイド ハッピーエンド', 'general_firstup': '2018-12-20 08:58:12', 'general_lastup': '2019-01-13 15:44:22', 'novel_type': 1, 'end': 1, 'general_all_no': 12, 'length': 12596, 'time': 26, 'isstop': 0, 'isr15': 1, 'isbl': 0, 'isgl': 0, 'iszankoku': 0, 'istensei': 0, 'istenni': 0, 'pc_or_k': 2, 'global_point': 12, 'fav_novel_cnt': 2, 'review_cnt': 0, 'all_point': 8, 'all_hyoka_cnt': 1, 'sasie_cnt': 0, 'kaiwaritu': 29, 'novelupdated_at': '2019-01-13 15:45:33', 'updated_at': '2019-01-13 15:48:07'}]
パラメータ内容
useridユーザーIDの指定
ハイフン(-)で区切ればOR検索
minlen小説の最小文字数の指定
maxlen小説の最大文字数の指定
length小説の文字数を指定
範囲指定する場合は最小文字数と最大文字数をハイフン(-)記号
ncodeNコードの指定
ハイフン(-)記号で区切ればNコードのOR検索
type小説タイプを指定
t:短編
r:連載中
er:完結済連載小説
re:すべての連載小説(連載中および完結済)
ter:短編と完結済連載小説

スポンサーリンク

出力

今までは出力できることを確かめていましたが,出力されているものが何を表しているのか触れていなかったので仕様を見ておきたいと思います.

パラメータ内容
allcount全小説出力
title小説名
ncodeNCODE
useridユーザーID
writer作者名
storyあらすじ
biggenre大ジャンル
genre小ジャンル
keywordキーワード
general_firstup初回掲載日
general_lastup最終掲載日
novel_type連載:1,短編:2
end短編,完結:0
連載中:1
general_all_no全掲載部分数,短編は1
length小説文字数
time読了時間
isstop長期連載停止中:1
それ以外:0
isr15R15かどうか
isblボーイズラブかどうか
isglガールズラブかどうか
iszankoku残酷な描写ありかどうか
istensei異世界転生かどうか
istenni異世界転移かどうか
pc_or_kケータイのみ:1
PCのみ:2
PCとケータイで投稿:3
global_point総合評価ポイント
fav_novel_cntブックマーク数
review_cntレビュー数
all_point評価点
all_hyoka_cnt評価者数
sasie_cnt挿絵の数
kaiwaritu会話率
novelupdated_at小説の更新日時
updated_at最終更新日時

さいごに

今回は条件抽出と出力内容の確認をしてみました.

次回はMongoDBにデータを保存していきたいと思います.

ABOUT ME
しまさん
高専→大学編入→大学院→? / 計算社会科学,ウェブマイニングなど / グレープフルーツと本が好き / SNS(Twitter,YouTube,Twitch)やVTuberのデータ分析屋 詳しいプロフィールはこちら≫ 投げ銭はコチラ