1.はじめに
Qiita初投稿です!
投稿日である現在、ラグビーW杯フランス大会真っ只中!世間もきっとラグビーで盛り上がっているだろうな!という思いから、学んだばかりのNode-REDとQiita APIを使って、Qiita記事からラグビーに関する記事がどの程度書かれているのか、また世間はラグビーに対してどの程度関心を持っているのかを調査してみました🏉🏉
2.環境準備
今回使用した環境は以下の通りです。
・Node-RED(FlowForge)
・Qiita API
3.実装開始
3-1.仮説と実装目標を立てる
まず仮説を2点立てて、それに沿ってQiita APIを用いてどのように実装が可能かをイメージしてみました。
【仮説】
① ラグビー関連の記事はトレンドとなったタイミングに集中しているのではないか?
② 記事が集中している年は世間の関心も高くいいね数が多いのではないか?
【実装目標】
・ Qiita記事のタイトルに"ラグビー"の文字を含む記事の投稿数を取得
・ 年毎に分けて件数を取得
・ 記事毎のいいね数を取得
3-2.Qiita APIを使ってみる
最初にNode-REDのhttp requestノードを使って、タイトルに"ラグビー"の文字列を含む記事を取得してみますが・・・
■タイトルにラグビーの文字を含む記事を取得
https://qiita.com/api/v2/items?page=1&per_page=100&query=title:ラグビー
結果は7件?少なすぎる。。。
Qiita記事をラグビーで検索した時は134件見つかった為、条件が悪いと思い詳しく調査を行ったところ、タイトルよりも本文中にラグビーの文字列を含む文書が多い事が判明しました。
タイトルからは上手く取得できない為、本文中に"ラグビー"の文字列を含む記事で取得してみたところ・・・
■本文中にラグビーの文字を含む記事を取得
https://qiita.com/api/v2/items?page=1&per_page=100&query=body:ラグビー
結果は100件以上!無事成功しました!!
基本となるデータの取得はできたので、次に2023年の記事のみを取得してみました。
■本文中にラグビーの文字を含む かつ 作成日が2023年の記事を取得
https://qiita.com/api/v2/items?page=1&per_page=100&query=body:ラグビー+created:>2023-01-01+created:<2023-10-19
2023年1月から現在までの記事のみ取得できた為、これも無事成功!
Qiita APIの準備はこれで完了しました!
3-3.Node-REDとQiita APIを組み合わせてみる
次はNode-REDとQiita APIを組み合わせてデータを取得してみました。
・ 想定通りのデータは取得できたが・・・
JSON形式の出力結果からいいね数をカウントするのは非常に大変・・・
そこでfunctionノードを追加して、タイトルといいね数を別途取得してみました。
■functionノード
let array_data = msg.payload;
let array_data01 = msg.payload;
let likes_count=[];
let title = [];
//記事のいいね数とタイトルを取得
for(let i=0;i<14;i++){
likes_count[i] = array_data[i].likes_count;
title[i] = array_data01[i].title;
}
msg.likes_count = likes_count;
msg.title = title;
return msg;
・ 無事ほしいデータが取得できました!
まだ少し見にくいですが、ラグビー関連の投稿数といいね数が取得できました!
これらを使用して、年別のデータ収集を行っていきます。
3-4.データの収集を行う
年別のラグビー記事の投稿数といいね数を取得するノードを作成します。
Node-REDとJSONは以下の通りとなります。
結果、年別の件数、いいね数、タイトルの一覧が取得ができました!!
JSON形式
[{"id":"2ad09c421d2bd55b","type":"inject","z":"4d08a5ef2eb210eb","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"inject","payloadType":"str","x":110,"y":300,"wires":[["0baffbaa19296cea","4f8723bccf7d4ffa","bb2769ef979d7173","e1e68ea939ad7833","8a1da05051ca1cb4","3ffd863903ecafa8","805f1372984f44cd","eeb70132f2995aa1","e939f97d955d5518","4febbfe33b16288b"]]},{"id":"4febbfe33b16288b","type":"http request","z":"4d08a5ef2eb210eb","name":"2023年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2023-01-01+created:%3C2023-10-19","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":140,"wires":[["bb582a5433e27c78"]]},{"id":"bb582a5433e27c78","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<14;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":140,"wires":[["802799123df5a0c8"]]},{"id":"802799123df5a0c8","type":"debug","z":"4d08a5ef2eb210eb","name":"結果23","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":140,"wires":[]},{"id":"4f8723bccf7d4ffa","type":"http request","z":"4d08a5ef2eb210eb","name":"2021年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2021-01-01+created:%3C2021-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":220,"wires":[["8cded6eb4fc0014e"]]},{"id":"0baffbaa19296cea","type":"http request","z":"4d08a5ef2eb210eb","name":"2022年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2022-01-01+created:%3C2022-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":180,"wires":[["b343e32a2a3ab0e5"]]},{"id":"bb2769ef979d7173","type":"http request","z":"4d08a5ef2eb210eb","name":"2020年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2020-01-01+created:%3C2020-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":260,"wires":[["8bcd3ba85e248bf5"]]},{"id":"e1e68ea939ad7833","type":"http request","z":"4d08a5ef2eb210eb","name":"2019年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2019-01-01+created:%3C2019-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":300,"wires":[["926a45223d76eb12"]]},{"id":"8a1da05051ca1cb4","type":"http request","z":"4d08a5ef2eb210eb","name":"2018年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2018-01-01+created:%3C2018-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":340,"wires":[["d86dfac114030e68"]]},{"id":"3ffd863903ecafa8","type":"http request","z":"4d08a5ef2eb210eb","name":"2017年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2017-01-01+created:%3C2017-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":380,"wires":[["8853e5853ef47f8b"]]},{"id":"805f1372984f44cd","type":"http request","z":"4d08a5ef2eb210eb","name":"2016年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2016-01-01+created:%3C2016-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":420,"wires":[["ef6355f342c8c032"]]},{"id":"eeb70132f2995aa1","type":"http request","z":"4d08a5ef2eb210eb","name":"2015年","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3E2015-01-01+created:%3C2015-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":460,"wires":[["7502493941c7b51f"]]},{"id":"e939f97d955d5518","type":"http request","z":"4d08a5ef2eb210eb","name":"2014年以前","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?page=1&per_page=100&query=body%3A%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%20created:%3C2014-12-31","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":330,"y":500,"wires":[["a7ed5ce8426dd560"]]},{"id":"a7ed5ce8426dd560","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<2;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":500,"wires":[["accdf3ff8a27983b"]]},{"id":"d86dfac114030e68","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<10;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":340,"wires":[["e04d4791e6c4830d"]]},{"id":"8cded6eb4fc0014e","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<19;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":220,"wires":[["4a340144545f1059"]]},{"id":"b343e32a2a3ab0e5","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<16;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":180,"wires":[["3d86011eea6c2d83"]]},{"id":"926a45223d76eb12","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<41;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":300,"wires":[["4c50e86601d7ed83"]]},{"id":"ef6355f342c8c032","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<3;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":420,"wires":[["ddca1c8902107664"]]},{"id":"8853e5853ef47f8b","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<2;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":380,"wires":[["17ce63fcaab1ba76"]]},{"id":"8bcd3ba85e248bf5","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<24;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":260,"wires":[["8485bffd912c6d61"]]},{"id":"7502493941c7b51f","type":"function","z":"4d08a5ef2eb210eb","name":"集計","func":"let array_data = msg.payload;\nlet array_data01 = msg.payload;\nlet likes_count=[];\nlet title = [];\n\n//記事ストック数を算出\nfor(let i=0;i<3;i++){\n likes_count[i] = array_data[i].likes_count;\n title[i] = array_data01[i].title;\n}\nmsg.likes_count = likes_count;\nmsg.title = title;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":460,"wires":[["11ad1d8bf306fe93"]]},{"id":"3d86011eea6c2d83","type":"debug","z":"4d08a5ef2eb210eb","name":"結果22","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":180,"wires":[]},{"id":"4a340144545f1059","type":"debug","z":"4d08a5ef2eb210eb","name":"結果21","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":220,"wires":[]},{"id":"8485bffd912c6d61","type":"debug","z":"4d08a5ef2eb210eb","name":"結果20","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":260,"wires":[]},{"id":"4c50e86601d7ed83","type":"debug","z":"4d08a5ef2eb210eb","name":"結果19","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":300,"wires":[]},{"id":"e04d4791e6c4830d","type":"debug","z":"4d08a5ef2eb210eb","name":"結果18","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":340,"wires":[]},{"id":"17ce63fcaab1ba76","type":"debug","z":"4d08a5ef2eb210eb","name":"結果17","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":380,"wires":[]},{"id":"ddca1c8902107664","type":"debug","z":"4d08a5ef2eb210eb","name":"結果16","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":420,"wires":[]},{"id":"11ad1d8bf306fe93","type":"debug","z":"4d08a5ef2eb210eb","name":"結果15","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":460,"wires":[]},{"id":"accdf3ff8a27983b","type":"debug","z":"4d08a5ef2eb210eb","name":"結果14以前","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":670,"y":500,"wires":[]}]
4.データの分析
4-1.取得データを分析してみる
取得したデータから、記事の件数と1記事あたりのいいね数の平均値を算出してグラフにしてみます。(1投稿あたりの平均いいね数は、[年のいいね数の合計 ÷ 年の投稿数の合計]で算出)
また、取得したデータからトレンドを分析する為の裏付け情報として、日本国内リーグの平均観客動員数をまとめたグラフも合わせて作成します。
■国内リーグの平均観客動員数
※国内リーグは12月~5月に開催の為トレンドとなった翌年に増加する傾向にあります
・ 投稿数は仮説通りの結果に
日本でW杯が開催された2019年は、記事の投稿数もダントツで多く、定通りの結果が得られました。また、投稿数のグラフの形は国内リーグの平均観客動員数の形にも似ており、世間のトレンドはQiita記事のトレンドにもつながっている事がわかりました。
・ 一方でいいね数はトレンドに関係せず・・・
投稿数は概ね想定通りであった一方で、いいね数のグラフは大きく差異があり、世間のトレンドに影響される結果とはなりませんでした。
4-2.結果の考察
今回のデータを分析して判明したポイントは以下の2点になります。
● Qiitaの記事で取り扱われる題材は世間のトレンドに影響される
● いいね数は世間のトレンドに影響を受ける事はない
Qiita記事の題材はその時の世間のトレンドに影響を受ける傾向にあり、その理由はテーマを選定のし易さや、世間の関心の集めやすさにあると考察します。
(私の今回のテーマもW杯フランス大会に便乗してます!!)
いいね数は記事のクオリティやどれ程参考になったかが重要であるため、トレンドによって増加するものではないと考察します。
5.おわりに
今回は学びたてほやほやのNode-REDとQiita APIを使用してみましたが、以下の点は最後まで解決できなかった為、引き続き学習を続けてより便利な使い方を習得していきたいと思いました!
・ JSON形式のデータが見にくいのでUTF-8形式にしたらデータが見切れる
・ データが見切れる為csv出力しようと思ったらwrite fileノードが使えない
・ 出力結果をまとめる作業は手動対応となってしまった
最後までお読み頂きありがとうございました!
アドバイスなどがあればぜひコメントを頂けますとうれしいです!!
またラグビーファンの方もぜひぜひコメントをお待ちしております!!!
参考にしたサイト
Qiita API v2 documentation - Qiita Developer
人気のあるタグでみんなはどんな記事を書いているのかトレンドを考察してみた