[JavaScript]なろうのランキングをAPIで一括取得する

  • このエントリーをはてなブックマークに追加

APIが使える環境があり、定期的にそれを使っているならちょっとコード化するだけで
やりたいことが数秒短縮できる、みたいな記事です。

やろうと思った経緯

夏頃ステイホームの暇さに煽られ、kindlePaperWhiteを購入しました。
暇つぶしに「小説家になろう」を読み続け数ヶ月、有名所を読み終えたため
まだ見ぬ掘り出しモノを探すためランキングをローラーするようになりました。

何度もサイトにアクセスしているため、いちいちアクセスするのが面倒になったのと
(**単純にランキングが多少見にくいみたいなところもある**)
現プロジェクトで使っているAPIのcall側が複雑で分かりにくいスパゲッティ実装であり
復習を兼ねてかんたんな実装を試してみたかったため、
見たいランキングだけnodeで取得してtext化するモジュールを作成しました。

やりたいこと

①パラメータ設定済みのAPIを叩きJSONを取得
②適当なファイルに出力

APIを叩きJSONを取得

rpmのrequestを入れて完成まで行ったのですがrequestは今年の2月頃から非推奨のため
axiosに変更しました。request使用が簡単すぎたので大丈夫かな?と思ったのですが
使ってみたら現場と同じだったり、Promiseだけでほぼ差異はありませんでした。

適当なファイルに出力

今回はcli出力だと見辛いかな?程度の文字数だけどリッチに見せたいような事もないので
簡易的にtextで出力するようにしました。

実装

ソース:https://github.com/sena-v/narouRankingToText


const axiosBase = require('axios') // ①に使用
const fs = require("fs"); // ②に使用

// urlと検索パラメータを保管
const url = 'https://api.syosetu.com/novelapi/api/';
const weeklyURL = '?genre=201&order=weeklypoint&of=t-n-w-s-k-gf-gl-l-nu';
const monthlyURL = '?genre=201&order=monthlypoint&of=t-n-w-s-k-gf-gl-l-nu';

const axios = axiosBase.create({
baseURL: url,
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
"User-Agent": "Mozilla/5.0",
},
responseType: 'json'
});

let outputText = null

const fileOutput = (text) => {

// weekly取得時は出力せずreturn
if(outputText === null) {
fs.writeFileSync("output.txt", '')
outputText = text;
return}

outputText = (outputText + text)
const arrText = outputText.split('\\n')
console.log(arrText)

try {
for(let txt of arrText) {
fs.appendFile("output.txt",txt+"\r\n",()=>{})
}

console.log("write end")
} catch (e) {
console.log(e)
}
}

const narouListGet = (adress) =>
axios.get("/" + adress).then((data) => fileOutput(JSON.stringify(data.data)))

narouListGet(weeklyURL)
narouListGet(monthlyURL)

楽さを重視したのでtext出力にしましたが、JSON加工だけできれば後フロントとの繋ぎだけなので
fsについては今回深く理解する必要はないかなと思ったため上書き更新による実装になっています。

実行結果

読んでみようかな、となる判断材料になる箇所だけ抜き出す形式にしたため、検索件数を増やすとか、
別ランキングを取得するところもパラメータ変更で対応できる形式となります。

止まったところ

api側使用について

userAgentが未設定の場合エラーページのhtmlがJSON返還されるため、
axiosのheaderに適当な値を追加してgetする形式としました。

fsモジュールappendFileの引数不足

fs.appendFile()は引数を3個取り、3個目がcallback形式でエラー出力に使用されるため
今回は特にエラーを考えない形で空関数を設定し回避しました。

まとめ

サイトopen→weekly一覧を撫でる→monthly一覧を撫でる、を1コマンドでできるようになったので
復習ついでとしては地味に時間短縮できるものができました。

・今回の実装だけの話
投稿系サイトにありえる「更新が止まっている物を読み始めても途中で止まり意味がない」問題を
今回はweekly/monthlyに上がってくる=更新止まっていない、としてケアしていますが、
暇があったらnarou.rbと連携して読了済み小説のタグ抽出から好きな小説の傾向を判断して
自動取得するとかの拡張もいいかもしれないなと思いました。

参考

[axios]axios の導入と簡単な使い方
[node.js] テキストファイルを読みこみ

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*

CAPTCHA