表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

ブックマーク機能を使うにはログインしてください。
9/15

パースしてシートに張り付けていこう

今回は得たデータをパース(分割)してシートに張り付けていきます。


サンプルコードをコピペすると空行が勝手に入るので、それを消して使ってください……。


すみません……

「さて今回からはパースについて説明していくよ」


「なんだか久しぶりな気がしますね」


「……ごめんね」


※長らくお待たせしました


「……そういえば今回はパースについてなんですね? あのパースってなんなんですか?」



「えーっと、パースっていうのはプログラムの機能・処理の一つで、一定の書式や文法に従って記述されたデータを解析し、プログラムで扱えるようなデータ構造の集合体に変換することだよ。


 よく『パーサ』(parser)あるいは『パーザ』とかいうよ」


「……すいません。あまりよく分からないのですが……」


「まぁ要するに単純な文字列の集まりを、データ分析しやすいように分解するものだと思ってもらえばいいよ。Excelでいうとこんな感じに、文字列をそれぞれの要素に分けてセルに入れていくそんなものだと理解してくらたらいいかな」


挿絵(By みてみん)

※A1のセルがパース前、B2:E6がパースした後です。

※この章でやるのは取得データを1つのセルに全部入れるのではなくそれぞれの要素ごとに分解することですね。


「そうなんだ。たしかに表に分けると見やすいですね」


「うん。見やすいだけではなくて集計分析しやすくなるよ。ということで、ここでは得られたデータをExcelのセルに1つ1つ格納していくやり方を教えるね。ちなみにパースのやり方はいっぱいあるから自分にあった方法を見つけてね。ここでは1つの例だけしかやらないし、これが正解というわけではないので注意ね」


「はーい」


「ということで簡単になろう小説APIのパース関数を作ったからこれを使う方法を教えていくね」


※忘れている方は最初から読み返してね♪

※動かなかったらメッセージください……


1.前回作成したエクセルファイルのSheet1のところに以下のプログラムをコピペしてね。

(Sheet名を変えたらその名称も変わります。)


その場合

SheetName = "Sheet1"

の""を変えたシート名にしてください。




■サンプル なろう小説APIパースサンプル■

*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*


Option Explicit


Private Sub CommandButton1_Click()


Dim i As Integer, j As Integer, k As Integer, Allcount As Long, LoopNum As Integer

Dim AryID As Variant, AryIDCaption As Variant, SplList() As String

Dim StrAPIData As String, StrGetCommand As String, SheetName As String

Dim buf As Variant, buf2 As Variant, strbuf As String


Application.ScreenUpdating = False 'デバッグするときはコメントアウト


'パースするための識別子の事前準備。

  'サンプルコードをコピペすると空行が勝手に入るので、それを消して使ってください……。赤くならなければOKです。


AryID = Array("title:", "ncode:", "userid:", "writer:", "story:", "biggenre:", " genre:" , "gensaku:", "keyword:", "general_firstup:", "general_lastup:", "novel_type:", "end:", "general_all_no:" , "length:", "time:", "isstop:", "isr15:", "isbl:", "isgl:", "iszankoku:", "istensei:" , "istenni:", "pc_or_k:", "global_point:", "fav_novel_cnt:", "review_cnt:", "all_point:", "all_hyoka_cnt:" , "sasie_cnt:", "kaiwaritu:", "novelupdated_at:", "updated_at:", "weekly_unique:")


AryIDCaption = Array("小説名", "Nコード", "ユーザID", "作者名", "あらすじ", "大ジャンル", "ジャンル" _

, "現在未使用項目", "キーワード", "初回掲載日", "最終掲載日", "連載の場合は1、短編の場合は2", "短編と完結は0連載中は1", "全掲載部分数" , "小説文字数", "読了時間", "長期連載停止中なら1", "R15", "ボーイズラブ", "ガールズラブ", "残酷な描写あり", "異世界転生" , "異世界転移", "投稿媒体(1ケータイ、2PC、3PCとケータイ)", " 総合評価ポイント", "ブックマーク数", "レビュー数", "評価点", "評価者数" , "挿絵の数", "会話率", "小説の更新日時", "最終更新日時", "週間ユニーク")


'Sheet名を変えた場合は""内を変えたシート名に変える

SheetName = "Sheet1"


Sheets(SheetName).Cells.Clear 'Sheetのクリア


'APIコマンド 並べ替えを総合評価順にする。※アレンジする場合は自分の出力したいものにする。(例題あり)

StrGetCommand = "https://api.syosetu.com/novelapi/api/?order=hyoka" '


StrAPIData = GetAPIData(StrGetCommand & "&lim=1") 'APIのデータを取得する。まずはデータ数を確認するため出力は1個にしておく


k = 1


'APIから取得したデータの要素の確認を行う


For i = 0 To UBound(AryID)

If InStr(StrAPIData, AryID(i)) <> 0 Then

Sheets(SheetName).Cells(1, k + 1) = AryIDCaption(i) 'Headerに記述していく

ReDim Preserve SplList(1 To k)

SplList(k) = AryID(i)

k = k + 1

End If

Next


'全体数の確認

buf = Split(StrAPIData, "allcount:")


Allcount = CLng(Left(buf(1), InStr(buf(1), vbLf) - 1))


Sheets(SheetName).Cells(1, 1) = Allcount 'A1には全件数を入れる


If Allcount > 500 Then '500以上の場合はループさせる

LoopNum = Application.WorksheetFunction.RoundUp(Allcount / 500, 0) 'Loop数のカウント 切り上げ

Else

LoopNum = 1

End If


If LoopNum > 4 Then LoopNum = 4 'max 2000件まで 4回分 そんなに必要なければ1とかにしても


For i = 1 To LoopNum


StrAPIData = GetAPIData(StrGetCommand & "&lim=500&st=" & ((i - 1) * 500 + 1)) '1, 501, 1001, 1501 stは取得開始番号


'それぞれの要素のパース

'Debug.Print StrAPIData


buf = Split(StrAPIData, SplList(1)) '1個めの要素で先に分割。


For j = 1 To UBound(buf) '小説数だけカウント


For k = 1 To UBound(SplList)


'Debug.Print buf(j)


If k = 1 Then '最初の項の処理

strbuf = Left(buf(j), InStr(buf(j), SplList(k + 1)) - 1)

ElseIf k = UBound(SplList) Then '最終項の処理

buf2 = Split(buf(j), SplList(k))

strbuf = buf2(1)

Else

buf2 = Split(buf(j), SplList(k))

strbuf = Left(buf2(1), InStr(buf2(1), SplList(k + 1)) - 1)

End If


Call strCleaern(strbuf, SplList(k)) '余計な空行などの除去


'分割した要素をCellに入れていく Variantで一括貼り付けすると高速化できる

Sheets(SheetName).Cells((i - 1) * 500 + j + 1, k + 1) = strbuf


Next

Next

Next


Application.ScreenUpdating = True


End Sub


'余計な改行コードと空白の除去 + 文字列の場合の特殊処理追加

Sub strCleaern(strbuf As String, strID As String)


With WorksheetFunction 'ワークシート関数の使用のため

strbuf = Trim(.Clean(strbuf)) '空行などの除去


Select Case strID


Case "story:", "title:", "keyword:", "writer:" '文字列が返るときの処理は若干特殊処理


If Left(strbuf, 1) = "|" Then strbuf = Right(strbuf, Len(strbuf) - 1)

If Left(strbuf, 1) = ">" Then strbuf = Right(strbuf, Len(strbuf) - 1)


strbuf = Trim(.Clean(strbuf)) 'あらすじの改行コードは残してもいいかもしれない。


If Left(strbuf, 1) = "|" Then strbuf = Right(strbuf, Len(strbuf) - 1) 'なぜか|が二つはいることもあるので削除

If Left(strbuf, 1) = ">" Then strbuf = Right(strbuf, Len(strbuf) - 1)


strbuf = Trim(.Clean(strbuf))


If IsNumeric(strbuf) Then strbuf = "'" & strbuf '文字列変換 数値だった場合に自動変換されるのを防ぐ

If IsDate(strbuf) Then strbuf = "'" & strbuf '文字列変換 日付だった場合に自動変換されるのを防ぐ

If Left(strbuf, 1) = "=" Then strbuf = "'" & strbuf '文字列変換 =が先頭だった場合に式に自動変換されてエラーが出るのを防ぐ


Case Else

If Right(strbuf, 1) = "-" Then strbuf = Left(strbuf, Len(strbuf) - 1) '-が入る場合の処理

End Select



End With

End Sub


*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*



挿絵(By みてみん)


挿絵(By みてみん)




「じゃぁ、これでテストボタンを押してみて」


※ボタンを押すとプログラムが走ります。だいたい10秒~30秒くらいで完了します。


挿絵(By みてみん)


「わ、すごい。急に表ができました。おぉ~。なんだか感動しました。ところでこれってなんのデータなんですか?」


「んーとね、これは総合ポイントの高い作品の上位2000位までのデータを一括で取得するプログラムだよ。これでExcelで扱える形式に変換されたし、次からそのデータを分析していこう」


「おぉー、ようやくですね。がんばります!」



■ ■- 以下パース補足 -■ ■


・Split関数 私は基本的にこの関数を使用してパースを行うことが多いです。


使い方は以下のサイトを見るとよいかと。

http://officetanaka.net/excel/vba/tips/tips62.htm


Split(元の文字列 , 区切り文字)


*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*

■https://api.syosetu.com/novelapi/api/?userid=1090932&lim=1■


---

-

allcount: 12

-

title: >

ランキング以外で「小説家になろう」の面白い小説を探したい! という方に必見。スコッパーな方々のためのレビュー情報サイトを紹介します。

ncode: N1243FL

userid: 1090932

writer: 夕月 悠里

story: |

ランキング以外で「小説家になろう」の面白い小説を探したい!

そんなスコッパーな方々のために作られたレビュー情報サイトの紹介です。

biggenre: 99

genre: 9903

gensaku:

keyword: >

スコッパー レビュー

関連サイト 面白い小説

情報サイト Twitter

general_firstup: 2019-04-14 12:21:12

general_lastup: 2019-04-14 12:39:41

novel_type: 2

end: 0

general_all_no: 1

length: 1281

time: 3

isstop: 0

isr15: 0

isbl: 0

isgl: 0

iszankoku: 0

istensei: 0

istenni: 0

pc_or_k: 2

global_point: 255

fav_novel_cnt: 15

review_cnt: 0

all_point: 225

all_hyoka_cnt: 24

sasie_cnt: 2

kaiwaritu: 19

novelupdated_at: 2019-04-14 12:39:41

updated_at: 2019-04-21 06:14:15


*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*


なろう小説APIの出力(YAML)ではこのようになります。

それぞれに識別が付いているのでそいつたちで区切っています。



またもう一つ使うことが多いのは

・Left関数 左から指定した文字数を抜き出す

LEFT(文字列,文字数)


・Right関数 右から指定した文字数を抜き出す

RIGHT(文字列,文字数)


・Len関数 文字列の長さを返す

LEN(文字列)


・Instr関数 指定した文字列の中に指定した文字が最初に含まれる

InStr( “検索対象となる文字列”, “検索する文字列”)



この辺りの関数を使えば、大体の形式に対応できると思います。


あんまり速度は重視してないのでこんな感じにしてますが、もっといいやり方があるかも知れませんね。


たとえばデータをJSON形式で取得してjavascriptオブジェクトを使ってパースするやり方もあります。


あとはpythonなんかだとYAMLパーサーがあるのでそれを使えば一発ですね。


色々とあるので自分にあった方法をお試しください。



■ ■- 取得データの応用例 -■ ■



今回は累計ポイント順のデータを得ましたが、ここの文字列を変えることで色々なデータが取得できます。


StrGetCommand = "https://api.syosetu.com/novelapi/api/?order=hyoka" '


『https://api.syosetu.com/novelapi/api/?order=hyoka』

を変化させて自分の好きな物を取得してみてください。


例を載せておくので色々と試してください

※詳細はおまけでやりますが、なろうデベロッパーの仕様をお確かめください。

https://dev.syosetu.com/man/api/



・感想が多い順

StrGetCommand = "https://api.syosetu.com/novelapi/api/?order=impressioncnt"


・レビューが多い順

StrGetCommand = "https://api.syosetu.com/novelapi/api/?order=reviewcnt"


・週間ユニークが多い順

StrGetCommand = "https://api.syosetu.com/novelapi/api/?order=weekly"


・ジャンル制限(大ジャンルが恋愛または文芸)

StrGetCommand = "https://api.syosetu.com/novelapi/api/?biggenre=1-3"


・文字数制限(文字数が2000文字から3000文字)

StrGetCommand = "https://api.syosetu.com/novelapi/api/?length=2000-3000"


・挿し絵数指定(挿絵が1つから5つまでの作品)

StrGetCommand = "https://api.syosetu.com/novelapi/api/?sasie=1-5"

評価をするにはログインしてください。
この作品をシェア
Twitter LINEで送る
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
小説家になろうを知ろうシリーズ
1. とあるスコッパーの備忘録
↑小説検索の方法を知ろう↑
2. 拝啓 エタりそうな作者様、エタが嫌いな読者様。
↑エタ(エターナル、更新停止)について知ろう↑
3. 拝復 応援されたい作者様、応援したい読者様。
↑削除、応援について知ろう↑

紹介したリンク
1. なろうデベロッパー
↑主なデータの取得元↑
2. 国立国会図書館法によるインターネット資料の収集について
↑ネットデータ収集の参考資料↑
3. 岡崎市立中央図書館事件
↑スクレイピングを行うときの注意↑
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

この作品はリンクフリーです。ご自由にリンク(紹介)してください。
この作品はスマートフォン対応です。スマートフォンかパソコンかを自動で判別し、適切なページを表示します。

↑ページトップへ