Don't wanna be here? Send us removal request.
Text
FastAPI × PostgreSQL:モデルなしで疎通確認する方法
今回は、FastAPI + SQLAlchemy + PostgreSQL 環境で、 ORMモデルを定義せずにDBへの接続確認を行う方法を紹介します。 自分のプロジェクト「Wonderpasnavi」の開発中に、実際に遭遇したエラーや学びも含めてまとめました。
環境構成
Python 3.11
FastAPI
SQLAlchemy
PostgreSQL(外部VPS)
Poetry(仮想環境管理)
Docker / docker compose
.env の設定
環境変数でDB接続URLを管理します。
DATABASE_URL=postgresql+psycopg2://wpnuser:[email protected]:5432/wonderpasnavi
接続確認用スクリプト test_db.py
モデルを定義せず、生のSQLを直接実行して接続確認します。
from sqlalchemy import text from db import db_engine def test_connection(): try: with db_engine.connect() as conn: result = conn.execute(text("SELECT max(at_t) FROM trk_waitingtime;")) print("接続成功!結果:", result.scalar()) except Exception as e: print("接続エラー:", e) if __name__ == "__main__": test_connection()
【注意】poetry環境下では直接 python test_db.py を実行してはダメ
Poetry はプロジェクトごとに 独自の仮想環境 を作成します。 そのため、以下のように直接実行してもライブラリが見つからずエラーになります:
python test_db.py ← ❌ sqlalchemy が import できない
正しい実行方法は以下:
poetry run python test_db.py
これにより poetry の仮想環境内で実行され、SQLAlchemy などのライブラリも正しく読み込まれます。
【注意】pydantic v2 での変更点:BaseSettings の移動
pydantic v2 以降、環境変数読み込みに使用していた BaseSettings は、pydantic-settings パッケージ に分離されました。
そのため、次のようなエラーが発生します:
pydantic.errors.PydanticImportError: `BaseSettings` has been moved to the `pydantic-settings` package.
対処法
1. 新パッケージを追加
poetry add pydantic-settings
2. インポート文を修正
from pydantic_settings import BaseSettings
おわりに
モデルを定義する前でも、こうした方法でDB疎通を確認できます。 FastAPIやSQLAlchemyの挙動を理解するのにとても良いステップです。 今後はORMモデルの定義やマイグレーションツール(Alembic)との連携も試して、より堅牢な構成にしていく予定です。
by Wonderpasnavi 開発記 🐭
0 notes
Text
データ収集バッチ専用スケジューラー
ディズニー待ち時間データをPythonで自動収集してみた!スケジューラー構築の裏側と改善点
こんにちは!本記事では、私が作成した「東京ディズニーランド&シーの待ち時間データ収集スクリプト」について紹介します。 今回は、Python + Selenium を用いてリアルタイムのアトラクション待ち時間をスクレイピングし、PostgreSQLに蓄積するシステムの全体像と、TkinterによるスケジューラーUI、さらに改善点についても触れていきます。
○ どんな仕組み?
まず、全体の流れを整理すると以下のようになります:
ユーザーがTkinterで作ったGUIアプリで収集開始時間を設定
スケジューラーが指定時刻になるとPythonのループが開始
Pythonスクリプトが、Seleniumを通じて東京ディズニーリゾートの公式サイトにアクセス
待ち時間や運営状況をスクレイピング
取得したデータをPostgreSQLへINSERT
LINE Notifyで進行状況(開始・終了・エラー)を通知
これらすべてを、ワンボタンで操作できるようにし、朝の収集スタートも自動化しています。
○ スクレイピング処理の工夫
【ポイント1】 ページ遷移せずにすべてのアトラクションをクロール
ディズニー公式サイトの構造上、各アトラ��ションごとに専用ページがあります。 このため、各アトラクションID(例:/tds/attraction/detail/219)に対して a[href] セレクタでリンク要素を取得し、対応する待ち時間や運営状況を .realtimeInformation 内からスクレイピングする設計です。
【ポイント2】 タグが見つからないときのフォールバック処理
以下のようなケース分けをして、タグが見つからなかった場合のリカバリ処理も行なっています。
待ち時間タグがない場合 → 999 で代替
運営状態が取得できない場合 → "★運営中" や "★運営状態不明" を挿入
【ポイント3】 ログ出力とエラーハンドリング
何が失敗したかを後から見直せるよう、各取得ごとにログを出力。 また、例外が発生した場合にはLINE Notifyに即時通知し、ログにも詳細を書き出します。
○ データベース構成と挿入処理
待ち時間情報と運営状況は別々のテーブル trk_waitingtime と trk_operation に保存しています。CREATE TABLE trk_waitingtime ( attr_id INT, waitingperiod TEXT, at_t TIMESTAMP ); CREATE TABLE trk_operation ( attr_id INT, condition TEXT, at_t TIMESTAMP );
挿入処理にはPythonの psycopg2 を使用。 データベースの認証情報は .env ファイルで管理し、セキュリティにも配慮しています。
○ TkinterのGUIでスケジュール起動
TkinterベースのGUIアプリも作成しており、次のような機能を備えています:
ドロップダウンで収集開始時刻を設定
ON/OFFボタンでスケジューラー起動切り替え
ステータス表示(時刻・収集状態など)
色味は柔らかなパステルカラーで設計し、実行中の安心感を演出しています。
○ 改善したい点
1. Seleniumの結構性なもたつさ
現在のSelenium実装では、Chromeを都度起動し全ページをスクレイピングしています。 ヘッドレス化&並列取得にすれば、待ち時間を大幅に短縮できそうです。
2. スケジューリングの汎用化
TkinterのUIでは柔軟なスケジュール設定がやや難しいため、cron的な設定(複数タイミングの指定)や日ごとのルール分岐も考えたいです。
3. データ重複の排除
既に同じ時間帯に記録がある場合はスキップする処理を導入して、無駄なINSERTを減らすとDBの成長も抑制できます。
4. 収集停止の条件
現在は 21:05 に強制終了していますが、サイトの更新停止なども検知して早期終了できるとよりスマートです。
○ まとめ
このPythonスクリプトは、
自作GUIで収集時刻を指定し
Webスクレイピングでディズニーのリアルタイムデータを取得し
PostgreSQLに保存
LINEで通知まで行う という、いわば"自動データ収集職人"のような仕組みです。
運用中の課題もありますが、数ヶ月以上この方法で安定稼働できており、今後の分析やルート提案アプリ「Wonderpasnavi」の裏側を支える重要なインフラになりそうです。
今後もこの仕組みの改善や、別テーマのデータ収集(天気・混雑度・アトラクション稼働率など)へと拡張していきたいと思います。
🍵 応援はこちらから:https://buymeacoffee.com/lira_dev
もし同じような収集システムを作りたい方がいれば、コメントで質問してください!
0 notes
Text
VS Codeで仮想環境が効かない!?Django開発環境構築でハマったエラーの全記録
この記事は、Windows環境でPythonとDjangoを使って開発を始めた際、Visual Studio Code(VS Code)上で仮想環境の設定に関して発生した複数のトラブルについて記録したものです。仮想環境を有効にしたはずなのにPythonが見つからない、Djangoサーバが起動しない、ライブラリが入っていない、など……。その一つ一つが地味に時間を削るものばかりで、この記事が誰かの参考になればと思って残しておきます。
PowerShellで仮想環境に入れない
最初のつまずきは「仮想環境のアクティベート」でした。私は PowerShell を使って以下のコマンドを実行しました。
venv\Scripts\activate
すると、以下のようなメッセージが返ってきました:
モジュール 'venv' を読み込むことができませんでした。
これは PowerShell では activate ではなく、Activate.ps1 を使う必要があるためです。
.\venv\Scripts\Activate.ps1
この修正で無事仮想環境に入ることができましたが、これはまだ始まりに過ぎませんでした。
仮想環境に入ったのにPythonが使えない
仮想環境に入った状態で Django の開発サーバーを起動しようとしました:
python manage.py runserver
しかし、なんと返ってきたエラーはこれ:
No Python at '"/usr/bin\python.exe'
WindowsでなぜUnix風のパス?しかも usr/bin の後に python.exe が混ざっているという奇妙な状態でした。
実はこれ、仮想環境が正しくアクティベートされているように見えて、VS Code が別の仮想環境(C:\Python\.venv)を参照していたことが原因でした。プロジェクト直下の .venv を使いたいのに、VS Code の設定が上位のグローバル仮想環境を見に行っていたのです。
where python が効かない
仮想環境内で where python を実行しても何も返ってきませんでした。そこで外部の cmd.exe を使って同じコマンドを打つと、次のように表示されました:
C:\Python\WonderPasNavi\.venv\Scripts\python.exe C:\Users\user\AppData\Local\Programs\Python\Python39-32\python.exe
この結果から、PowerShell 内での仮想環境のパスが正常に反映されていないことが分かりました。どうやら VS Code の PowerShell ターミナルでは環境変数 PATH の更新がうまく行われていなかったようです。
見えない .vscode と仮想環境指定
VS Code の仮想環境設定は通常、プロジェクト直下の .vscode/settings.json に保存されます。しかしこのフォルダが作成されていなければ、VS Code がどの Python を使うべきか迷ってしまいます。今回は .vscode フォルダが存在しておらず、設定ファイルもない状態でした。結果、Python拡張機能が以前の仮想環境を優先してしまっていたわけです。
Djangoサーバは起動したが…
仮想環境を再度正しくアクティベートして、python manage.py runserver を実行。すると、今度は次のエラーが表示されました:
ModuleNotFoundError: No module named 'django_bootstrap5'
そうです、ライブラリが入ってなかったんです。プロジェクトの settings.py に 'django_bootstrap5' が記述されているにも関わらず、依存パッケージが仮想環境にインストールされていませんでした。
対処法は単純です。
pip install django-bootstrap5
これでエラーは解消され、ついにサーバが起動しました。ここまでくるのに何時間かかったことか……。
まとめ:「この苦労を…」
VS Code + Python + Django の仮想環境構築は、一見簡単そうに見えて、罠が多いです。
仮想環境の activate の方法は PowerShell / CMD で異なる
VS Code の Python拡張は過去の設定を引きずることがある
ターミナルごとに仮想環境の有効化状態が違う可能性がある
仮想環境の python.exe が本当に使われているか確認するには where python が超重要
この苦労を、未来の自分や他の誰かが繰り返さないように、この記事を残します。
「仮想環境、ちゃんと動いてる?」って思ったら、まずは where python で確認しよう。
タグ: #Python #Django #VSCode #仮想環境 #トラブルシューティング #初心者向け
2 notes
·
View notes
Text
「作る前に"乗る"」開発中アプリを妄想で遊んでみた!使用シナリオ紹介
こんにちは!現在開発中のアプリ「Wonderpasnavi(ワンダーパスナビ)」は、ディズニーランド&ディズニーシーを効率よく、そして“誰かと一緒”でもストレスなく回るためのルート提案アプリです。
実は私自身、このアプリが完成してからじゃなくて、“開発中”にも関わらず、ちょっとずつ妄想で遊んでしまっているのです(笑) 今回は、どんな風にこのアプリを使ったら楽しめるのか、現段階の構想をもとに使用シナリオとして紹介します。
シナリオ1:朝イチから閉園までがっつり「制覇プラン」
想定ユーザー:毎回スタンバイでバリバリ回るのが好きなグループ(年パス勢、ガチ勢)
入園後すぐに「当日モード」に切り替え、事前にピックアップしたアトラクションを表示。
ルートはAIが最短経路&待ち時間の少なさをもとに提案。
「ビッグサンダーマウンテン → ホーンテッドマンション → イッツアスモールワールド → 昼食」など、朝から午後の行動が一目瞭然。
各アトラクション間の歩行ルートもパークの簡易地図とアイコンで視覚的に表示。
レストランやワゴンの混雑状況も表示し、ポップコーンの味と販売場所の好みに合わせて休憩ルートも調整。
このシナリオの面白いところは、“現在地からだけでなく、次の地点を常に先読み”して、疲れすぎないペースを提案するところ。閉園まで無理なくまわれるよう、夕方には比較的空いているシアター系アトラクションが組み込まれたりします。
シナリオ2:「我慢ゼロ」な友人に合わせるプラン
想定ユーザー:待ち時間0分じゃないと機嫌が悪くなる友人とのインパ計画(笑)
ユーザー設定で「我慢耐性:ゼロ」と入力。
リアルタイムで更新される“現在のスタンバイ時間”と“予想待ち時間”をもとに、現在地から最も近く、待ち時間がほぼゼロのアトラクションだけが提案される。
パレードやショーを中心に回る提案も。場所取りのタイミングも通知してくれる。
座れるカフェやレストランも表示。
このシナリオ、ある意味“付き合う側のため”の機能(笑)。アトラクション数こそ少ないですが、快適さとストレスフリーを重視するルート構築が可能になります。
シナリオ3:「地図��読めない」家族向け・親子ナビ
想定ユーザー:方向音痴な親と、歩く距離に敏感な子ども
目的地は「ビジュアルで」選択(アイコンやイラスト中心)。
移動中は「方向矢印」と「現在地マーク」が常に大きく表示される簡易マップ。
「次にどっちへ進むか」を歩く方向で誘導(方角ではなく、身体の向きベース)。
ベビーカー向けのルートや休憩ポイントも表示。
視覚的なナビに特化することで、アプリ自体が「話しかけなくても伝わる家族のナビゲーター」に変身。特に地図が苦手な大人にとって大きな助けになります。
シナリオ4:「一緒に行けないけど…」遠隔体験シミュレーション
想定ユーザー:遠方に住んでいてしばらく行けない人、計画段階を楽しむ人
実際の待ち時間データや天気データを使って「仮想一日ルート」を提案。
行ったつもりで、1日をシミュレートできる。
「もし行ったら」シリーズのブログネタにも使える!
これは開発者である私自身が一番楽しんでいる使い方かもしれません(笑)。過去の待ち時間傾向から、次の三連休に行くとどんなスケジュールになるか…なんて妄想してテンションを上げてます!
おわりに:開発中でもすでに遊べてる!?
「Wonderpasnavi」は、ただのナビゲーションアプリではありません。
“誰かと一緒に行くからこそ発生する問題”を最初から想定。
プランニング段階から当日まで、使い手の心理に寄り添う構成。
実装前から妄想が膨らむほど、設計段階で既にワクワクしているアプリです。
現在はWeb APIとフロントアプリの開発を少しずつ進めながら、こういったシナリオを元に「どんな使い方をしても楽しい!」を目指して改善中です。
これからもこうした使用シナリオをどんどん妄想しながら、ブログやBuy Me a Coffeeにて進捗を共有していきますね!
☕ Buy Me a Coffee: lira_dev
読んでくれてありがとう!あなたなら、どんな風にこのアプリを遊びたいですか?
0 notes
Text
wwwだけリダイレクトされてた!? 独自ドメインとNginxの罠
ある日、ふと自分の独自ドメイン bigfanofdisney.com にアクセスしてみると、なんと「Welcome to nginx!」のページが表示されてしまった……。
一方で、www.bigfanofdisney.com にアクセスすると、ちゃんとTumblrのブログにリダイレクトされてる。
「えっ!? なんで `www` だけ期待通り動いてるの……?」 その時の混乱と、仕組みをきちんと理解して設定を直した経験を、この記事に備忘録としてまとめておこうと思います。
問題:ドメインによってアクセス先がバラバラだった
自分の環境は以下のような構成になっていました:
サブドメイン blog.bigfanofdisney.com: Tumblrブログ本体
www.bigfanofdisney.com: ちゃんと blog. にリダイレクトされる
ルートドメイン bigfanofdisney.com: なぜかNginxの初期ページ(Welcome to nginx!)が出る
同じドメインなのに、なぜか挙動が違う。この正体は、実は以下の2つに隠されていました:
DNS(ドメインの向き先)
Nginx(Webサーバー)の設定
原因1:DNS設定がバラバラ
ドメインには「www」付きと無しで、別の設定ができます。 たとえば、次のようなDNS設定がされていたとします: bigfanofdisney.com → 自分のVPSのIPアドレス www.bigfanofdisney.com → TumblrのCNAME (domains.tumblr.com)
この場合、www 付きのアクセスはTumblrへ飛びますが、裸のドメイン bigfanofdisney.com はVPS上の Nginx に届いてしまいます。
つまり、見ている場所がそもそも違うのです。
原因2:Nginxが意図したリダイレクトをしていなかった
Nginxの設定ファイル(/etc/nginx/sites-available/default など)には次のような記述が必要でした:
server {
listen 80; listen [::]:80;
server_name bigfanofdisney.com www.bigfanofdisney.com;
return 301 https://bigfanofdisney.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name bigfanofdisney.com www.bigfanofdisney.com;
ssl_certificate /etc/letsencrypt/live/bigfanofdisney.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bigfanofdisney.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
return 301 https://blog.bigfanofdisney.com$request_uri;
}
}
ところが、当初はこの設定がコメントアウトされていたり、途中で切れていたりと、正しく動作していなかったのです。
その結果、Nginxはデフォルトの「ようこそ!」ページを出してしまっていたというわけです。
解決策:Nginxに正しいリダイレクトルールを設定する
修正方法は次の2ステップです:
Nginxの設定ファイルで、すべてのリクエストを blog.bigfanofdisney.com にリダイレクト
設定反映後、nginx -t で文法チェック → sudo systemctl reload nginx
さらに、DNS側でも `bigfanofdisney.com` と `www` を同じ方向(VPS or Tumblr)に合わせておくことで、挙動が安定します。
まとめ:ドメインの「入り口」って意外とややこしい!
今回のように、DNSとNginxの両方の設定が一致していないと、意図したWebサイトにたどり着かないということが起こります。
とくにTumblrなどの外部サービスと独自ドメインを組み合わせる場合、wwwと裸ドメインの扱いに注意が必要です。
アクセスが集中してから気づいては遅い!ということで、 すべてのバリエーションでドメインが想定通り動くかは、あらかじめ確認しておきましょう。
このブログ「BigFanOfDisney.com」では、こうしたインフラ構築やデプロイの知見も発信していきます。
次回は、Let's Encryptを使ったSSL証明書の設定について書こうと思います。
📌応援はこちら → BuyMeACoffee.com/lira_dev
0 notes
Text
「地図が読めない人」のためのUI設計 — ビジュアルでナビをする工夫
「地図が読めない人」のためのUI設計 — ビジュアルでナビをする工夫
テーマパークでよく耳にするフレーズのひとつに、「地図見てもわからないからついていくわ」があります。 方向感覚に自信がない人、地図の記号が苦手な人、そもそもスマホの地図アプリにすら不安がある人…。 実際、「迷わずに次のアトラクションへ行く」という行為そのものが、地図リテラシーの有無に大きく左右されているのです。
私は、そうした“地図が読めない人”のためのナビゲーションUIを開発したいと考えています。
まだ「声」は集まっていないけれど
現在、私は「Wonderpasnavi」というプロジェクトで、ディズニーランドやディズニーシーを効率よく巡るためのアプリを開発中です。 この記事で紹介するのは、今まさに構想段階にある「地図が読めない人向けUI」の設計方針について。 実際のユーザーからの声はこれから集めていきますが、過去の体験や観察から出てきた課題感をもとに話を進めます。
課題:現在地がわかっても「どっち向いてるのか」がわからない
Googleマップなどの汎用地図アプリでは、現在地は表示されても「どこが正面なのか」がわからないという声は多いです。 また、園内のマップと実際の風景が一致しないと混乱する人も。 そこで私のアプリでは、
アイコン化されたアトラクション
実際の景色に似たランドマーク(建物や門)
コンパス機能による進行方向の明示
などを組み合わせた“超ビジュアル志向マップ”を目指したいと考えています。
「今日行くところだけ」表示する当日モード
アトラクションは40個以上あって、ひと目で全てを把握するのは困難です。 なので、あらかじめピックアップした数か所だけを目立たせる“当日モード”を用意したいと考えています。 マップ上ではアイコンが浮き出るように表示され、進む方向をアニメーションで誘導。これにより、地図を読めない人でも「行きたいところだけ」に集中できます。
現在地をオリジナルマップに反映できるのか?
現在、調査中なのが「自作の地図にGPS情報を反映できるか」という点です。 AppleのMapKitやCoreLocationを使えば座標は取得できますが、テーマパーク独自のマップとどう重ねるかが技術的な課題。 マップのスケーリングや回転に対応しつつ、正確に「いまここ」を示すための工夫が必要です。
この部分はまだ手探りで、ベストプラクティスを模索中です。 今後記事として経過を共有したいと思います。
おわりに
「地図が読めないから不安」 その声に正面から応えるようなアプリを作りたい。 使う人に「ナビに頼っていいんだ」と思ってもらえる設計が、きっと体験全体を優しくするはずです。
開発を応援してくださる方は、Buy Me a Coffee ☕ もぜひ覗いてみてくださいね。
0 notes
Text
「0分待ちじゃなきゃ乗れない」友人に合わせた "我慢ゼロ"ルート提案は可能なのか?
テーマパークに行くのが好きな人ほど、一緒に行くメンバー選びにはちょっと慎重になりますよね。 特に「少しでも並ぶのはムリ」「休憩がこまめに必要」「座れないと不機嫌になる」……そんな“我慢ゼロタイプ”の友人と一緒だと、こちらが気を遣いすぎてぐったりしてしまうことも。
でも、それって本当に“我慢ゼロな人”が悪いのでしょうか? もしかすると、彼らに合ったルートを事前に設計できれば、みんながハッピーになれるのでは…?
なぜ“我慢ゼロ”タイプといると疲れるのか?
我慢ゼロタイプの特徴は「行列が苦手」「空腹に耐えられない」「スケジュール変更が難しい」といった、即時性重視の感覚にあります。 一見わがままにも思えるけど、実は「自分の感情に正直で繊細」な人が多いんです。 問題は、それに合わせるプランを考えるのが難しいという点。
Wonderpasnaviがやりたいこと
私が開発しているWonderpasnaviでは、“我慢ゼロモード”という発想を取り入れようと考えています。 これは、「とにかく待ち時間の少ないルート」「近くにすぐ休憩できる場所がある」「人混みを避けた導線」をベースにした、感情優先ルートの提案です。
例えば、アトラクションに乗る前にポップコーンを買っておく、飲み物が切れる前にベンチ近くを通るようにする、混みやすいショップをあえて外すなど、徹底的に“つまずきを排除”した設計ができるはずです。
それって現実的?
結論から言うと、「100%待ち時間ゼロ」は無理です。でも「我慢の少ない体験」は設計できます。 統計的に空いている時間帯に狙って動く。事前に選ばれた“行きたい場所だけ”を巡る。 そして、何より大事なのは「自分で調整しなくていい」という安心感。 これは、同伴者にも本人にも優しいナビゲーションだと思うのです。
さいごに
我慢ゼロな友人とのテーマパーク巡り。 面倒と思うか、攻略対象と思うかで体験の質は大きく変わります。 Wonderpasnaviでは、そうした“個別ニーズ”に寄り添ったルート提案を目指して開発中です。
応援いただける方は、Buy Me a Coffee ☕でも支援受付中です!
0 notes
Text
Let's EncryptでSSLを無料導入!Nginxと組み合わせてHTTPS化する手順
WebサイトやAPIの運用においてSSL(HTTPS)化は欠かせません。特にフォーム入力やログイン機能がある場合、通信の暗号化はユーザーの信頼を得る上で大きなポイントになります。 今回は無料で利用できるLet's Encryptを使用し、Nginxと組み合わせてSSL証明書を取得・設定する流れを解説します。
1. HTTPS化のメリット
通信内容の暗号化により盗聴や改ざんを防止
SEOに有利(GoogleがHTTPSを推奨)
ブラウザに「保護された通信」と表示されることで安心感を与える
2. Let's Encryptとは?
Let's Encryptは、無料でSSL証明書を発行してくれる認証局(CA)です。ACMEというプロトコルを通じて、自動で証明書を取得・更新できます。
3. 導入前提条件
サーバーにNginxがインストールされている
独自ドメインを保有しており、Nginxのサーバーに向けてDNS設定済み
80番ポート(HTTP)と443番ポート(HTTPS)が開放されている
4. Certbotを使ったSSL証明書の取得
以下はUbuntu系サーバーでの例です。sudo apt update sudo apt install certbot python3-certbot-nginx
証明書の取得とNginx設定の自動化:sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
インタラクティブな質問に答えていくだけで、自動で証明書取得とNginx設定が完了します。
5. 自動更新設定
Let's Encryptの証明書は90日間有効ですが、自動更新を設定しておけば安心です。sudo crontab -e
以下のような行を追加します(1日1回チェック):0 3 * * * /usr/bin/certbot renew --quiet
6. NginxのSSL設定の例
server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; location / { proxy_pass http://localhost:8000; include proxy_params; } }
HTTPからHTTPSへのリダイレクトを設定したい場合は次のように追加します:server { listen 80; server_name yourdomain.com; return 301 https://$host$request_uri; }
まとめ
SSLの導入は以前に比べてはるかに簡単になりました。Let's EncryptとCertbotを使えば、無料かつ自動化された仕組みで、安全な通信環境をすぐに構築できます。 本サイトでも同様の手順でSSL化を行っており、サーバーコストを抑えつつ安全な配信を実現しています。
ブログがお役に立ったら Buy Me a Coffee ☕ で応援いただけたら嬉しいです。
0 notes
Text
1年間のディズニー待ち時間データをどうやって集めたか? スクレイピング設計と工夫
こんにちは!このブログでは、ディズニーランド&ディズニーシーの最適ルート提案アプリ「Wonderpasnavi」の開発裏側を紹介しています。 今回は、その中核ともいえる「待ち時間データの取得方法」について詳しくお話します。
📊 1年間、地道にデータ収集していました
Wonderpasnaviでは、過去の混雑状況を元にしたルート提案機能を構築するために、 約1年間にわたって東京ディズニーランド&シーのアトラクション待ち時間を自動取得し、データベースに蓄積してきました。
使用したのはPythonです。対象ページはJavaScriptで動的に更新される構造のため、 最初はrequestsではうまく取得できず、Seleniumを導入しました。 データ取得処理はスケジューラー(自作)を通じて、1日何度も定期的に回す構成にしました。
⚖️ 倫理とルールへの配慮
このプロジェクトでは、クローリングやBotによる過度なアクセスは一切行っていません。 公開情報のみを、あくまで人間と同等のペースで取得する設計にしています。 また、非公式APIなどにも頼らず、リスクやルール違反のない方法で地道に記録しています。
📌 スケジューラー構成の工夫
早朝〜閉園までのピークタイムを重点的に記録
天候や曜日、イベント有無などのラベルを別途保存
同じアトラクションが複数パークに存在する場合はID管理
休日と平日で記録頻度を変更
🌟 実際の活用
このデータを使って、最も効率的な巡り方や、ファストパスなしで楽しむルート、 「待てない人向け」や「夕方から入園する人向け」など、状況に応じた提案を行う予定です。
☕ サポートも歓迎しています
このプロジェクトは個人開発で行っており、データ取得や管理のサーバー費用などは自己負担です。 ご興味を持っていただけた方は、Buy Me a Coffee で応援していただけると嬉しいです!
次回は、このデータを活用したルート探索アルゴリズムや、バックエンドAPIの構成について紹介予定です。お楽しみに!
0 notes
Text
【やってみた】ディズニーランドのアトラクション最適ルートを計算するアルゴリズムを作ってみた
「どうやったら効率よくディズニーランドのアトラクションをまわれるか?」 そう思ったのがきっかけで、旅行好きプログラマーとして、本気でルート最適化アルゴリズムを組んでみました。 その過程と結果をまとめてみます。
やりたかったこと
アトラクションの待ち時間と移動時間を考慮して、最短で回れるルートを提案したい
時間帯によって変動する待ち時間を統計的に予測して活用したい
最終的にはアプリとして誰かの役に立つ形にしたい
使った技術
Python(データ収集+スケジューラー+アルゴリズム)
FastAPI(Web API化)
PostgreSQL(時系列データ保存)
独自アルゴリズム(巡回セールスマン問題 + 予測モデル)
仕組み
1. データ収集(自作スケジューラー + スクレイピング)
1年ほどかけて、Pythonで作った自作スケジューラーを使ってアトラクションの待ち時間を定期取得。 Webクローリングは禁止されている可能性があるため、対象ページに負荷をかけないよう静かにスクレイピングを行いました。 非公式APIなどは使っていません。データはPostgreSQLに蓄積して時系列として扱えるようにしました。
2. 待ち時間の未来予測
曜日・時間帯ごとの統計から「予測待ち時間」を生成。 たとえば「13時のビッグサンダーマウンテンは平均35分待ち」などを仮データとして使います。
3. 移動時間も含めたルート計算アルゴリズム
単純な巡回セールスマン問題(TSP)では「移動距離」だけですが、ここでは「待ち時間 + 移動時間」の合計時間が最短になるように調整。
# 擬似コード 全アトラクションの順列を生成 各順序に対して 各アトラクションの訪問時間を仮定 → その時刻の予測待ち時間を取得 → 前の地点からの移動時間を足す 最も総所要時間が短い順序を採用
4. Web APIとして公開
計算結果は FastAPI 経由で JSON で返せるように実装。iPhoneアプリ側から呼び出せる形で整備しました。
ちょっと詰まったところ
アトラクション数が増えると順列全探索では処理が重くなる(対策:部分探索 + 制限付き選択)
天候・イベント日・季節による変動の予測はまだ不十分
データ収集のタイミング精度により若干のブレあり
面白かったこと
アルゴリズムとデータだけで「今行くならここが最適!」というルートを出せたのは感動。 行き先の決定がロジックで支援できるというのは、テーマパークの体験に新しい視点を加えると思います。
今後の展望
アトラクションの優先度をユーザーが選べるようにする
混雑しにくいゾーンを考慮した避けルートモードの実装
iPhoneアプリと連携し、リアルタイム更新できるようにする
おわりに
「夢の国」なのに、かなりロジカルに攻めてしまった感じですが…… 効率よく回りたい派の人や、技術ネタとしても面白く感じてもらえたら嬉しいです。 次はアプリとしてリリースできたらまた書きます!
0 notes
Text
【実際に試した】NginxでルートドメインをTumblrブログにリダイレクトした記録
今回は、私のサイトである bigfanofdisney.com を Tumblr ブログの blog.bigfanofdisney.com にリダイレクトさせる設定と、同じ Nginx サーバで Django を使ったアプリ(room.bigfanofdisney.com)も同時に動かすという、 一見ハマりがちな構成に挑戦しました。
結論から言うと、「できました」。疲れた…!
動作環境
Ubuntu 22.04 LTS
Nginx 1.18.0
Certbot (Let's Encrypt)
Django + uWSGI
Tumblr(カスタムドメイン: blog.bigfanofdisney.com)
目的
bigfanofdisney.com / www.bigfanofdisney.com のアクセスを Tumblr に301リダイレクト
同じサーバで room.bigfanofdisney.com の Django アプリを配信
設定手順
1. DNSのAレコード確認
bigfanofdisney.com, www.bigfanofdisney.com が自分のVPSを指すAレコードになっていることを確認。 Tumblr用の blog.bigfanofdisney.com は Tumblr指定のIP(例: 66.6.44.4)へ。
2. CertbotでSSL証明書取得
sudo certbot --nginx -d bigfanofdisney.com -d www.bigfanofdisney.com
最初は失敗したけど、DNS設定を直したら無事成功!
3. Nginxのdefault設定を修正
● HTTP リダイレクト
server { listen 80; listen [::]:80; server_name bigfanofdisney.com www.bigfanofdisney.com;return 301 https://bigfanofdisney.com$request_uri;
}
● HTTPS リダイレクト
server { listen 443 ssl; listen [::]:443 ssl; server_name bigfanofdisney.com www.bigfanofdisney.com;ssl_certificate /etc/letsencrypt/live/bigfanofdisney.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/bigfanofdisney.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { return 301 https://blog.bigfanofdisney.com$request_uri; }
}
4. Django用のconf.d設定
/etc/nginx/conf.d/wonderpasnavi_nginx.conf に Django 用の HTTPS + uWSGI 設定を記述。 Certbot が default に勝手に追記していた分は削除しました。
server { listen 443 ssl http2; server_name room.bigfanofdisney.com;ssl_certificate /etc/letsencrypt/live/room.bigfanofdisney.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/room.bigfanofdisney.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location /static/ { alias /home/ubuntu/wonderpasnavi/wonderpasnavi/static/; } location / { include /home/ubuntu/wonderpasnavi/wonderpasnavi/uwsgi_params; uwsgi_pass unix:/var/run/uwsgi.webapppackage/master.sock; }
}
結果
bigfanofdisney.com → Tumblr に301リダイレクトを確認 ✅
room.bigfanofdisney.com → Djangoアプリ表示 ✅
HTTPS通信も正常 ✅
Nginxのserverブロック競合も解消 ✅
感想
疲れた。 一見簡単そうに見えて、ちょっとでも誤ると「そっちのSSL証明書で返しちゃった」みたいな 予期せぬ挙動になったりして、Nginxのserverブロックは本当にロジックが必要。
でも、一つひとつ確認して、設定ファイルの内容と証明書の有無を確認しながらやっていけば確実に実現できる! 同じような構成に悩む人の参考になれば嬉しいです。
0 notes
Text
FastAPI × PostgreSQL でWeb API構築中!
こんにちは!現在、ディズニーランド&シーをもっと快適に楽しむためのルート提案アプリ「Wonderpasnavi」の開発を進めています。
今日はその中でも、バックエンドで使っている FastAPI × PostgreSQL の構成について紹介します。
✅ ORMにはSQLAlchemyを使用
ORMには軽快に動作して学習コストも低めな「SQLAlchemy」を選びました。 公式チュートリアルをベースに、以下のような構成でセッションとベースモデルを管理しています。
# api/db.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from dotenv import load_dotenv
import os
load_dotenv() DATABASE_URL = os.getenv("DATABASE_URL")
engine = create_engine(DATABASE_URL, echo=True)
SessionLocal = sessionmaker(autocommit=False,
autoflush=False, bind=engine)
Base = declarative_base()
あとはFastAPIルーター内で Depends(get_db) を使ってセッションを取得し、非同期にデータ操作ができます。
🐘 なぜ PostgreSQL?
実は仕事でよくPostgreSQLを目にしていたこともあり、自然な選択でした。 それに加えて、このプロジェクトでは地理情報や時系列データも扱う予定があるため、 PostGISなどの拡張性が高い点もありがたいポイントでした。
🧪 テストも簡単に書けるように設計中
今後、データ予測部分やルート計算アルゴリズムのテストを充実させたいと思っています。 モデル定義の変更に強く、メンテ性の高い構成に整えているところです。
☕ 応援してくれる方へ
このプロジェクトは完全自主開発で行っています。 もし応援してくださる方がいれば、Buy Me a Coffee のページから支援していただけたらとても励みになります!
👉 buymeacoffee.com/lira_dev
今後も開発進捗や裏話をこのブログで発信していくので、 ぜひチェックしてもらえたらうれしいです😊
0 notes
Text
はじめまして、Wonderpasnavi 開発ブログです!
こんにちは。このブログでは現在開発中のアプリ Wonderpasnavi の進捗を中心に、技術的な気づきや工夫、つまずきポイントの共有などを行っていきます。
アプリの目的は、ディズニーランド・ディズニーシーの「最適なめぐり方」を提案すること。FastAPI × PostgreSQL を使って Web API を構築し、iPhone アプリ(Swift)でその情報を受け取って表示する構成になっています。
このブログで取り上げる予定のテーマ
開発日誌・進捗報告:例「FastAPI × PostgreSQLでAPI構築中。ORMの書き方まとめ」
機能紹介:例「ディズニーシー最短ルートを計算してみた」
設計・裏話:例「なぜMySQLじゃなくPostgreSQLにしたのか?」
インフラ・運用:例「Docker上でFastAPIを本番公開するまで」
トラブルと解決策:例「macOSでRuby3系ビルドが通らなかった件」
もし技術的な話題に興味がある方、同じような開発をしている方がいれば、ぜひフォロー・シェアしていただけると嬉しいです😊
サーバー代をまかなうために BuyMeACoffee も設置予定です☕
今後とも Wonderpasnavi 開発ブログ をよろしくお願いします!
0 notes