初の個人開発TravelPackHubをリリースしました。

2024/10/29に公開

こちらです。
travelpackhub.com

https://github.com/KazumaWada/TravelPackHub

これを作る前のプログラミング学習歴や方法

Progateやドットインストールをやった後に、RubyonRailsでブログサイトを作りました。その後Recursionというコンピューターサイエンスが学べるサイトで学習しました。(これらの学習は約2年間。アプリケーションの開発期間は5ヶ月間くらいです。)

どんなアプリケーションか

「海外へ行く時の必要な持ち物リスト」です。

あるウェブサイトから「海外 持ち物」でヒットした記事をスクレイピングし(約7000記事)、記事内で紹介されている持ち物(Amazonリンク付き)をリストとしてまとめました。

なぜこれを作ろうと思ったか

「せっかく作るなら収益化してみたい」と思いどのように収益化できるアプリケーションを作ろうか調べていたところ、ジャバ • ザ • ハットリさんのこの記事を見つけました。

開設後3週間で収益10万円を得た個人開発サイトでやったことの全部を公開する - Qiita

この記事内で説明されているアプリケーションはこちらです。

憶測ですが、このアプリケーションはAmazonのアソシエイトIDをスクレイピングしてきた各技術書(Amazonリンク)に貼り、ユーザーが購入したら紹介料として収益が発生するのではないかと思いました。

このやり方をそのまま真似して、自分の興味のある分野で作ろうと思いました。

「自分の興味がある分野は何だろう?」と考えました。

僕は大学を卒業してから現在ワーキングホリデーで海外生活3年目に突入します。

それなら「海外」「英語」に関連する分野ならアプリケーション作成の道のりが長くても興味があるので続けられると思いました。そしてスクレイピングしてくるデータはAmazonの商品として存在していなければいけなかったのでその事について考えていると、「海外に持って行く持ち物」ならいけそう(自分の興味のある分野かつAmazonリンクが貼れて収益化ができそう)と思いました。

そしてサイト名をTravelPackHub(海外への持ち物が集まったハブ)という名前に決めてそれを作る事にしました。

技術

フロントエンド: HTML/CSS/Javascript(デザインはBootstrap)

バックエンド: Node.js(スクレイピングはpuppeteer)

データベース: MySQL

インフラ: Docker

デプロイに使用したソフトウェア: Heroku

技術選定理由:
以前からJavaScriptでコードを書いていた事が多く、慣れていたのでJavaScriptにしました。フレームワークは使用していません。(理由は後述します)

開発中に起こった問題にどのように対処したか

起こった問題01

JavaScriptのフレームワークの書き方が分からない

原因と対処01

Next.js(React), Angular, Vueなどのモダンな技術があり、ZennやQiitaの記事を見ていると個人開発やポートフォリオまたは業務で使っている方々がいますが、それを使って個人開発を進めるとそのフレームワークの学習に時間を取られ開発スピードが遅くなってしまうと考えていました。僕は早くリリースして「個人開発をリリースできた」という成功体験が欲しかったので、書き方を既に知っている生のJavaScriptで書いていく事にしました。(機会があれば学んでいきたいです。。)

起こった問題02

ローカル環境でスクレイピング中に変数が差していたメモリが超過してタイムアウトエラー

原因と対処02

  • スクレイピングしてきた大量のデータをひとつの変数に一気に格納しようとしていたのが原因で起こりました
  • スクレイピングしている途中でpupetteerがたくさんのタブを開きすぎていた。(webサイトの各記事内へ移動しその中のAmazonリンクを探し出すというのを7000件ほどやったのでたくさんタブを開くことになった。)

変数が指し示すメモリが上限に達する可能性があるという事を理解し、ある程度データが変数に格納されたらファイルに書き出し、変数を初期化するというループに書き換えました。

    let batchSize = 15;
    let articlesBatch = [];
    let processedCount = 0;
    const maxToProcess = 6500; //url i want to scrape has approximatly 7000 so i set below 7000 to make sure no error occur.
    
    for (const article of articles) {
      if (processedCount >= maxToProcess) {
        console.log(`Reached limit of ${maxToProcess} articles. Stopping.`);
        break;
      }
      console.log("Processing article:", article);
      await processArticle(page, article);
      articlesBatch.push(article);
      processedCount++;
      console.log("processedCount", processedCount);

      // If the batch size exceeds the limit, write to the file
      if (articlesBatch.length >= batchSize / 3) {
        //pushed amazonLink,title,imgs into articlesBatch.
        appendToFile('articleWithAmazon.json', articlesBatch);
        console.log(`Inserted batch of ${articlesBatch.length} articles into the file.`);
        articlesBatch = []; // Clear the batch
      }
    }

起こった問題03

Heroku上でスクレイピングを実行して、メモリが超過した。

原因と対処03

ローカルでは先ほどにも書いた、変数にある程度データが入ったらファイルに書き出して変数を初期化するという方法で実行できたのですが、heroku上ではメモリを保存できる量が自分のローカル環境と違うのか詳しくは分かりませんが、本番環境でスクレイピング中にエラーが発生してしまいました。

そもそもHerokuのサーバー内で何が起こっているのか詳しくわからず、その中で大量のデータを取得するコードを実行するのは良くないと思い、ローカルでスクレイピングを実行し、そのデータをファイルに書き出し、Heroku上ではその書き出されたファイルを読み込むのみにしました。

つまり、ローカルでのみスクレイピングする関数を実行し、本番環境ではその関数をコメントアウトしてHerokuに上げました。

app.get('/start', async(req,res) =>{
  try{
    //webサイトから記事をスクレイプする関数
    //await scrapeData(); //commentout will be removed in local when scraping needed
    //各記事内に入ってAmazonリンクをスクレイプする関数
    //await getAmazon(); //commentout will be removed in local when scraping needed
    //上記の関数の結果を全てファイルに書き込んだら、本番ではDBに挿入するだけにする。 
    await insertArticlesAndAmazonsToDB();//active in production.
    console.log("done!!!");
    //res.status(200).send('scrape done');
  }catch{
    res.status(500).send('scrapeData() not started...')
  }
})

起こった問題04

AI(cursor)に頼りすぎてデバックに時間がかかった。(制作期間が5ヶ月かかった原因の一つ)

原因と対処04

手間を省くために主要な関数の実装をAIに任せた結果、デバックをする時にコードを読む時間がかかったり、自分の理解の範囲を超えた書き方をしていた部分がありました。

自分でコード全体をコントロールできていない感じがして、(関数を実行してエラーが起こったらどこが原因が分からず怖かった。)もう一度スクラッチから書き直しました。

簡単なCSSの実装など、エラーが起こってもぜんたいに影響を及ぼさないコードはAIに頼りました。

得た学び

  • 億劫だけど、時間を無駄にしないために個人の技術ブログではなく公式を読む。

  • 自分で作りながら学ぶのが一番学習効率が高い。全て自分ごととして責任を持って考えることができるから。

  • とりあえずリリースして成功体験を積むために、機能を最低限にしてリリースしたのが良かった。(これから追加機能をアップデートしていく予定です。)

おわりに

今まで独学でエンジニアの人と関わった事がないので文中で僕の知識が偏っていたり、誤認識している部分があったかもしれません。

次はどうやってサイトにアクセスしてくれるユーザーを増やしたらいいのか考えて実行したり、新しいアプリケーションを作ったりしていきます。AIも活用して開発スピードを上げていきたいです。

仕事を探しています。

🙇kazumawadaa@gmail.com

https://github.com/KazumaWada

Discussion