پروژه مسکن‌اسکن

#side-project#nextjs#maplibre#deckgl#web-scraping
نقشه‌ای از تهران که آگهی‌های اجاره مسکن به همراه خطوط مترو روی اون نمایش داده شده

داستان از کجا شروع شد

حدود ۲ سال پیش یکی از دوستانم می‌خواست تو تهران، همراه یکی دیگه از دوستاش، خونه اجاره کنه. هر دو دانشجو بودن و پروسه چالش‌برانگیزی داشتن، چون باید هم‌زمان نزدیکی به محل کار، دانشگاه و خطوط مترو رو در نظر می‌گرفتن.

این موضوع رو به‌صورت کژوال با من در میون گذاشته بودن، و من تو وقت آزادم پروژه‌ای ساختم به اسم مسکن‌اسکن. این پروژه دیتای مربوط به اجاره‌های تهران رو از سایت‌ها و منابع مختلف (دیوار، شیپور، کلید و کاشانو) جمع‌آوری می‌کرد و روی نقشه نشون می‌داد. اون موقع از Leaflet برای نقشه استفاده کردم و خطوط مترو رو هم به‌صورت پیش‌فرض روش آورده بودم.

وقتی پروژه رو به دوستام معرفی کردم و ازش استفاده کردن، تونستن خونه‌های مدنظرشون رو راحت‌تر پیدا کنن. یه حس خیلی خوبیه وقتی یه پروژه خلاقانه بتونه یه مشکل واقعی رو حل کنه؛ پروژه‌های تکراری مثل فروشگاه یا Todo List این هیجان رو برام ندارن.

بعد از اینکه نیاز دوستام برطرف شد، پروژه رو کنار گذاشتم. حدود ۲ سال از اون موقع گذشت. الان دیوار بیشتر ویژگی‌هایی که برای مسکن‌اسکن در نظر داشتم رو خودش داره، و به نظرم این پروژه دیگه ارزش تبدیل شدن به یه محصول تجاری رو نداره؛ اما برای یه دمو تو رزومه می‌تونه خوب باشه.

بازسازی حرفه‌ای پروژه

این بار اومدم پروژه و معماریش رو به‌صورت حرفه‌ای بازنویسی کنم و سعی کردم مناسب‌ترین گزینه‌ها و کتابخونه‌ها رو براش انتخاب کنم؛ یه پروژه Next.js با MapLibre و Deck.gl برای هندل کردن نقشه و دیتا.

کتابخونه Deck.gl زیرمجموعه vis.gl هست، از کتابخونه‌های نقشه‌محوری که شرکت Uber پشتشه. این شرکت کتابخونه‌های مختلفی رو تحت نام vis.gl اوپن‌سورس کرده.

تغییر در منابع

برای نسخه جدید، منابع رو دوباره بررسی کردم و به‌جای کاشانو از MrEstate استفاده کردم، چون کاشانو وقتی چک کردم اصلاً اطلاعاتی رو در اختیار عموم نمی‌ذاشت.

به استخراج اطلاعات از وب، Scraping گفته می‌شه؛ مقوله‌ای که حتی دوره‌های آموزشی خودش رو هم داره. معمولاً سایت‌ها سعی می‌کنن باهاش مقابله کنن و نذارن اطلاعاتشون جای دیگه‌ای استفاده بشه، ولی اغلب فقط کار رو سخت‌تر می‌کنن، نه اینکه کلاً راهش رو ببندن.

دیوار هم همین‌طور بود؛ نسبت به دو سال پیش سعی کرده بود گرفتن اطلاعات رو سخت‌تر کنه و از روش‌های مختلفی مثل Rate Limit و احراز هویت برای جلوگیری ازش استفاده می‌کرد. تقریباً می‌شه گفت برخلاف اکثر سایت‌ها، حرفه‌ای عمل کرده بود. دیوار به سخت‌ترین منبع برای گرفتن اطلاعات تبدیل شده بود، ولی چون باارزش‌ترین منبع هم بود، نمی‌شد نادیده‌اش گرفت.

یه روز نشستم و سایت رو کامل بررسی کردم و یه تکنیکی به کار بستم که حتی هوش مصنوعی هم از خلاقیتش به وجد اومد. روش پیچیده‌ای بود، ولی ارزشش رو داشت؛ با این روش تونستم چند صد هزار داده رو تو فقط چند دقیقه بگیرم.

در نهایت کد مربوط به Scraper تکمیل شد و داده‌ها داخل یه دیتابیس Postgres ذخیره و به‌روز می‌شدن. فرانت هم داده‌ها رو از دیتابیس خود پروژه دریافت می‌کنه و روی نقشه نشون می‌ده.

امکانات پروژه

تو این نسخه، فیلترهای مختلف و حتی خلاقانه، دارک‌مود، و انواع لایه‌های نقشه به همراه مترو و BRT رو داریم که می‌شه فعال و غیرفعالشون کرد.

همچنین کاربر وقتی آیتمی با ویژگی‌های مدنظرش پیدا بشه، با پیامک یا ایمیل ازش مطلع می‌شه.

این پروژه از کامپوننت‌های کاستوم‌شده Shadcn و کتابخونه‌هایی مثل Tanstack Virtual، Tanstack Query و Zustand استفاده می‌کنه. یه‌سری Unit Test و End-to-End Test هم بهش اضافه کردم.

در نهایت وقتی پروژه آماده بود، با کمک AI و چند تا AI Skill حرفه‌ای، یه Landing Page براش زدم و دموی پروژه رو بهش وصل کردم.

الان کجاست

پروژه جالب و کاربردی بود، ولی چون الان دیوار اکثر ویژگی‌ها رو خودش اضافه کرده و منابع دیگه (شیپور، کلید و…) در مقایسه با دیوار سهم ناچیزی دارن، تصمیم گرفتم پروژه رو در حد یه دمو نگه دارم. برای همین بخش Scraper، که مسئول استخراج، آماده‌سازی و ذخیره اطلاعات جدید بود رو خاموش کردم تا فرانت پروژه صرفاً با داده‌های دمو قابل مشاهده باشه.

برای دمو از Netlify و NeonDB استفاده شده.

لینک‌ها و منابع