ワードクラウドを自作ニュースアプリに追加してみた

はじめに この間Node.jsで 多言語Webニュースアプリ 作ってみました https://www.multitrue.news ニュースのタイトルと概要だけではつまらないので、単語の出現頻度によって直近一週間のニュースからワードクラウド作って、一目で世の中の出来事を確認できたら面白そうじゃないかと思いながら、ワードクラウドをニュースアプリに追加してみました。 詳細 ソースはこちらから確認できます。 https://github.com/aibazhang/multitrue 下準備 日本語と中国語などは英語と異なり、単語と単語の間スペースがないので、形態素解析が必要です。簡略化するために、今回は英語のワードクラウドのみを作ることにしました。人称代名詞や助動詞のようなStop Wordsをワードクラウドに出しても意味がないので、NLTKの英語Stop Words辞書を利用します。 https://gist.github.com/sebleier/554280 また、単語の出現頻度を集計するヘルプ関数を作成します。いい感じライブラリもありますが、できるだけdependencyを減らしたいので、自分で実装することにしました。ただ、全ての単語を最終的に大文字に変換します。 src/utils/countWordsFrequency.js const stopwords = require('./stopwords-en.json'); // English stopwords via https://gist.github.com/sebleier/554280 const countWordsFrequency = (sentences) => { const result = {}; // remove punctuation and split by space const terms = sentences.toLowerCase().match(/[a-zA-Z]+/g); terms.forEach((e) => { if (!stopwords.stopwords.includes(e)) { const name = e.toUpperCase(); if (result[name]) { result[name] += 1; } else { result[name] = 1; } } }); return Object.entries(result) .map(([key, value]) => ({ name: key, value, })) .sort((a, b) => b.value - a.value); }; module.exports = countWordsFrequency; ニュース記事の単語出現頻度を計算 続いて、英語ニュースを収集するcontrollerに単語頻度を計算するロジックを組み込みます。今回利用しているNewsAPIはニュースの本文を取得できないため、タイトルと概要から単語出現頻度を計算し、ニュース・メタ情報と一緒にレスポンスに追加します。(収集期間のview-config.jsonから日単位で設定できます)今考えるとやはり単語出現頻度の計算とニュースの取得を分けたほうが良いかもしれません。 src/controllers/viewsController.js exports.getHeadlinesUS = catchAsync(async (req, res) => { const news = await News.find({ category: 'general', country: 'us' }) .sort('-publishedAt') .limit(viewConfig.limit); const articlesTitleDesc = await News.find({ category: 'general', country: 'us', publishedAt: { $gt: Date.now() - viewConfig.wordscloud.dateRangeDay * 24 * 60 * 60 * 1000, }, }).select('title description'); const wordsFrequency = calcWordFrequncyInArticles(articlesTitleDesc); res.status(200).render('index', { countryMeta: { flag: '🇺🇸', title: 'Top Stories', code: 'us', }, news, wordsFrequency, }); }); 計算結果をフロントに渡す echarts-wordcloudというライブラリでワードクラウドを描きます。 https://github.com/ecomfe/echarts-wordcloud ...

May 14, 2022 · Me

Web開発ど素人がNode.jsで多言語Webニュースアプリ作ってみた

目的 筆者自身はトリリンガル(自称)のため、簡単に日本語、英語、中国語などの複数の言語のホットニュースを読めるサービスががあると便利だなとずっと思っていました。「Google Newsで良くない?」って言われそうなところですが、Google Newsはやや使いづらいと感じました。 例えば、 言語を切り替えるのに「言語地域→候補から選ぶ→更新」3回クリックする必要がある 本当にヘッドライトしか閲覧したくないのに、「おすすめ」や「ピックアップ」などがうるさい モバイルのweb版が見づらい・アプリをダウンロードしたくない 芸能ニュースにまったく興味がないため、ニュースの表示をカスタマイズしたい また、やってみないと(何かを残さないと)学んだ技術をすぐ忘れるのはもったいないのも考えて、多言語ニュースWebアプリを自作するという発想に至りました。 使った技術 バックエンド NodeJS Express フロントエンド インタラクションがほぼないため、フレームワークは使っておらず、DOMをいじっただけ CSSは Start Bootstrap の無料テンプレートを使用 DB MongoDB インフラ Heroku コスト 毎月7ドルだけです!!(Heroku Hobbyの料金) 成果物 https://www.multitrue.news https://github.com/aibazhang/multitrue それでは、詳細を解説していきます。 下準備 ニュースはどこから収集するか 最初はニュース収集するかについてけっこう時間を費やしました。ニュース関連のAPIがかなり多いですが、 ある程度の無料枠がある 多言語のニュースが簡単に取れる 使いやすさ 3つの観点から考えて、 NewsAPI と News data の2つのAPIに絞りました。ただ、後々 News data は言語を指定しても他の言語のニュースが混ざっていることがあると気づいたので(例えば、言語を日本語と指定したにも関わらず、日本関連の英語ニュースが出てくる)、 NewsAPI 一択となりました。ちなみに、 こちら の記事はNewAPIについて詳しく説明しています。また、RSSなど他の人が作ったニュースAPIを使わないという方法もあるようですが、今回は試していなかったです。 データベース ニュース情報を収集するAPIを見つけましたが、ユーザがリクエストを投げるたびに、NewsAPIに叩くのは明らかに現実ではないので、ニュースを保存するDBが必要です。データ量が少ないかつ永久無料枠がベストなので、 MongoDB@Atlas を選びました。AWSとかにいい感じにデポロイしてくれるし、便利です。(無料枠の上限は500MB)また、テーブルはせいぜい1つ、2つくらい、リレーションも特にないはずなので、RDBを使う必要もありませんでした。 フロントエンド CSSから実装するはだるいので、Start Bootstrapにある Clean blog を使わせてもらいました。(感謝) 詳細 システム構成はこんな感じです。図を見ていただくとわかると思いますが、特にややこしいことをやっていないです。 定期的にNewsAPIからデータと取って、Mongodbに入れます ユーザからのリクエストが来る度に、バックエンドでhtml(正確にいうとpug)を作って、レスポンスを返します。いわゆるSSR(Server Side Rendering)ですね。 コスト面とシンプルさを考えているため、デポロイはHerokuというクラウドプラットフォームサービスを利用しています NewsAPIからMongodb データの定期取得ために、Node.jsのスクリプトを書きました。 NewsAPIの無料枠は100req/dayそして複数の言語のニュースを取得したいといった制約があるので、cronを使って一日の取得回数を制限しています。data-import-config.jsonはルートの下にあるデータをインポートする際のconfigファイルです。 ...

April 18, 2022 · Me