Qiitaの記事、10000件?!
こちらの記事「Qiitaの記事をランダムに読める API / サービス を4時間ぐらいで作った」を見て私も「Qiitaの最新記事10000件、取ってみよ!」と思いついたのでございます。
さっそくコーディング
上記記事のGithubリポジトリ https://github.com/redshoga/random-qiita-api を参考にしつつ、軽量な Http Client
らしい 「phin」を使って意気揚々とプログラムを作成いたしました。
まずはプロジェクトの準備から。
$ npm init
...
$ npm i phin
で〜package.json
のscripts
に"start":"node indes.js",
を追記してnpm start
コマンドでindex.js
が実行されるように仕掛け、以下のような感じでindex.js
を作成いたします。
const p = require('phin');
const fs = require('fs');
(async ()=>{
const TOKEN = '...';
// 1ページあたり100件は固定
const q = ((n) => (p) => `?page=${p}&per_page=${n}`)(100);
for(let i = 1 ;i <= 100; i++) {
const res = await p({
'url' : 'https://qiita.com/api/v2/items' + q(i),
'headers' :{
'Authorization' : `Bearer ${TOKEN}`
},
'parse': 'json'});
fs.writeFile(`./items/qiita_item_${i}.json`, JSON.stringify(res.body, '', ' '));
}
})();
Qiita の APIは認証キーがないと1時間に60回までのリクエストしか送れないため、短時間に100ページを取得して「最新の10000万件」を取ってくることができないのです。
というわけで、TOKEN
で定義している認証キーをこちらの「Qitta APIのヘルプ#認証認可」のページを参照して取得します。今回は手っ取り早く、"ユーザーの管理画面"からサクッと取得してきました。
ついでにクエリパラメータの作成で、ちょっぴりカリー化(「3歳娘「パパ、関数をカリー化して?」」をかじった程度)を試してみたり、jsonのフォーマットでインデント指定してみたり。
そして実行、ポチッとな!
いよいよ npm start
で実行してみます!
$ npm start
...
(node:13149) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
at maybeCallback (fs.js:128:9)
at Object.writeFile (fs.js:1158:14)
...
ERR_INVALID_CALLBACKッ! ERR_INVALID_CALLBACKッッ!!! ガーン!!!( ̄◇ ̄;)!!!
writeFile
で Callback must be a function
のエラーってなんだそりゃ?!
node.jsの公式ドキュメントをちゃんと確認
はい、node.jsの公式ヘルプを覗くと・・・
https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_writefile_file_data_options_callback
fs.writeFile(file, data[, options], callback)
・・・いつの間にか必須になっていたんですね、第3引数。ていうか、非同期になっていたのですね・・・
ってことで、callback
は必須です。
ちなみに、更新履歴は・・・
Version | Changes |
---|---|
v10.10.0 | The data parameter can now be any TypedArray or a DataView. |
v10.0.0 | The callback parameter is no longer optional. Not passing it will throw a TypeError at runtime. |
v7.4.0 | The data parameter can now be a Uint8Array. |
v7.0.0 | The callback parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013. |
v5.0.0 | The file parameter can be a file descriptor now. |
v0.1.29 | Added in: v0.1.29 |
Oh... The callback parameter is no longer optional.
の文字が踊る。。。
v.7
の時点で必須だったかぁ・・・
というわけで、以下のようにコールバックを追加して再チャレンジいたしました。
const p = require('phin');
const fs = require('fs');
(async ()=>{
const TOKEN = '....';
// 1ページあたり100件は固定
const q = ((n) => (p) => `?page=${p}&per_page=${n}`)(100);
for(let i = 1 ;i <= 100; i++) {
const res = await p({
'url' : 'https://qiita.com/api/v2/items' + q(i),
'headers' :{
'Authorization' : `Bearer ${TOKEN}`
},
'parse': 'json'});
fs.writeFile(`./items/qiita_item_${i}.json`, JSON.stringify(res.body, '', ' '), (err)=>{
if(err) console.log(`error!::${err}`);
});
}
})();
はい、こちらのコードで無事にjsonファイル100個、10000件の記事データが取得できました。
このjsonでこれから〇〇なことや、××をことを試してみたいと思います♪
参考ページ
- Qiitaの記事をランダムに読める API / サービス を4時間ぐらいで作った
- Github: Qiitaの最新の10000件の記事からランダムでURLを取得するAPI
- Github: Phin
- Phin Document
- Qiita API v2 ドキュメント
- 3歳娘「パパ、関数をカリー化して?」
- JSON.stringify() - JavaScript | MDN
- File System | Node.js v10.16.0 Documentation
宣伝
JSネタ、こちらもどうぞ〜!