آموزش ساخت ابزار دانلود پست اینستاگرام با API

دانلود پست اینستاگرام

فهرست مطلب

اگر تا حالا خواسته‌اید یک ابزار حرفه‌ای برای دانلود پست اینستاگرام بسازید که نه حساب را به خطر بیندازد، نه پایداری داشته باشد، باید با API رسمی Meta یعنی Instagram Graph API آشنا شوید. در این مقاله قدم‌به‌قدم یاد می‌گیرید چطور با دریافت API اینستاگرام، لینک مدیا را از پست‌های حساب Business یا Creator خودتان استخراج کنید و فایل را ذخیره کنید. قبل از هر چیز باید یک نکته‌ی مهم را بدانید: API رسمی اینستاگرام در ۲۰۲۶ فقط به اطلاعات حساب‌هایی که توسط کاربر تأیید شده‌اند دسترسی می‌دهد، نه پست‌های عمومی هر حساب دلخواه. این محدودیت عمدی است و هدف از آن حفاظت از حریم خصوصی کاربران است.

چرا API رسمی؟ مقایسه با ابزارهای غیررسمی

وقتی کسی می‌گوید «ابزار دانلود پست اینستاگرام بساز»، اولین چیزی که به ذهن می‌رسد ابزارهای اسکرپ یا ربات‌های غیررسمی است. اما این ابزارها مشکلات جدی دارند: با هر آپدیت اینستاگرام ممکن است از کار بیفتند، ریسک مسدود شدن حساب را به‌شدت بالا می‌برند و در مواردی که قرار است برای یک کسب‌وکار استفاده شوند، پایداری لازم را ندارند. در مقابل، API رسمی Meta یک زیرساخت تأییدشده است که Meta از آن پشتیبانی می‌کند و با هر آپدیت اینستاگرام، خودش به‌روزرسانی می‌شود.

محدودیت مهم: فقط حساب‌های Business یا Creator

یکی از مهم‌ترین محدودیت‌هایی که باید از ابتدا بدانید این است که Graph API اینستاگرام در ۲۰۲۶ فقط برای حساب‌های Business یا Creator که به یک صفحه‌ی فیسبوک متصل هستند در دسترس است. Basic Display API که قبلاً به حساب‌های شخصی هم دسترسی می‌داد، از دسامبر ۲۰۲۴ به‌طور کامل منسوخ شد. این یعنی اگر می‌خواهید ابزار شما روی حساب‌های شخصی هم کار کند، باید از رویکردهای دیگری استفاده کنید.

پیش‌نیازهای ساخت ابزار دانلود پست اینستاگرام

قبل از نوشتن حتی یک خط کد، باید زیرساخت لازم را آماده کنید. این مرحله ممکن است چند روز وقت ببرد، اما یک‌بار که انجام شد، پایه‌ای می‌سازد که تمام پروژه روی آن استوار خواهد بود.

  • یک حساب Business یا Creator در اینستاگرام (نه حساب شخصی)
  • یک صفحه‌ی فیسبوک که به حساب اینستاگرام متصل باشد
  • یک حساب Meta Developer فعال و تأییدشده
  • ساخت یک App در Meta Developer Portal
  • دریافت مجوزهای لازم: instagram_basic و instagram_manage_media
  • دریافت Access Token (کوتاه‌مدت یا بلندمدت)

تفاوت Access Token کوتاه‌مدت و بلندمدت

یکی از اشتباهات رایج توسعه‌دهندگان تازه‌کار این است که از Token کوتاه‌مدت در محیط پروداکشن استفاده می‌کنند. Token کوتاه‌مدت بعد از حدود یک ساعت منقضی می‌شود و می‌تواند باعث قطع ناگهانی سرویس شود. Token بلندمدت تا ۶۰ روز معتبر است، اما باید هر ۵۰ تا ۵۵ روز یک‌بار به‌صورت خودکار تجدید شود. برای یک ابزار دانلود که قرار است مداوم کار کند، پیاده‌سازی فرآیند تجدید خودکار Token از همان ابتدا ضروری است.

معماری کلی ابزار دانلود پست اینستاگرام

قبل از ورود به کد، بهتر است معماری کلی سیستم را در ذهن داشته باشید. یک ابزار دانلود پست اینستاگرام با API رسمی از چند مرحله‌ی اصلی تشکیل می‌شود که هرکدام بر روی مرحله‌ی قبل بنا می‌شوند.

  1. احراز هویت OAuth و دریافت Access Token
  2. فراخوانی API برای دریافت لیست پست‌های حساب
  3. دریافت اطلاعات هر پست شامل لینک مدیا، نوع فایل و توضیحات
  4. دانلود فایل از لینک media_url
  5. ذخیره‌سازی فایل با نام‌گذاری مناسب

جدول endpoint های اصلی برای دانلود پست

برای ساخت این ابزار به چند endpoint اصلی نیاز دارید. جدول زیر مهم‌ترین آن‌ها را خلاصه کرده است:

Endpoint کاربرد فیلدهای مهم
GET /{ig-user-id}/media دریافت لیست پست‌ها id, media_type, timestamp
GET /{ig-media-id} اطلاعات یک پست خاص media_url, thumbnail_url, caption
GET /{ig-media-id}/children تصاویر کاروسل id, media_url
GET /{ig-user-id}/stories استوری‌های فعال media_url, media_type

نمونه کد: دریافت لیست پست‌ها و لینک دانلود با Python

حالا وقت کد نوشتن است. در ادامه یک اسکریپت کامل Python می‌بینید که لیست پست‌های حساب شما را دریافت می‌کند، لینک مدیای هر پست را استخراج می‌کند و فایل را دانلود و ذخیره می‌کند.


import requests
import os
from datetime import datetime


ACCESS_TOKEN = "YOUR_LONG_LIVED_TOKEN"
IG_USER_ID = "YOUR_IG_USER_ID"
BASE_URL = "https://graph.facebook.com/v21.0"
SAVE_DIR = "instagram_downloads"

os.makedirs(SAVE_DIR, exist_ok=True)


def get_media_list(limit=10):
    """دریافت لیست آخرین پست‌های حساب"""
    url = f"{BASE_URL}/{IG_USER_ID}/media"
    params = {
        "fields": "id,media_type,media_url,thumbnail_url,caption,timestamp",
        "limit": limit,
        "access_token": ACCESS_TOKEN
    }
    response = requests.get(url, params=params)
    response.raise_for_status()
    return response.json().get("data", [])


def get_carousel_children(media_id):
    """دریافت تصاویر یک پست کاروسل"""
    url = f"{BASE_URL}/{media_id}/children"
    params = {
        "fields": "id,media_url,media_type",
        "access_token": ACCESS_TOKEN
    }
    response = requests.get(url, params=params)
    response.raise_for_status()
    return response.json().get("data", [])


def download_file(url, filename):
    """دانلود فایل از لینک مدیا"""
    response = requests.get(url, stream=True)
    response.raise_for_status()
    filepath = os.path.join(SAVE_DIR, filename)
    with open(filepath, "wb") as f:
        for chunk in response.iter_content(chunk_size=8192):
            f.write(chunk)
    print(f"دانلود شد: {filepath}")
    return filepath


def process_media(media):
    """پردازش هر پست و دانلود فایل مربوطه"""
    media_id = media["id"]
    media_type = media.get("media_type")
    timestamp = media.get("timestamp", "")[:10]

    if media_type == "IMAGE":
        url = media.get("media_url")
        filename = f"{timestamp}_{media_id}.jpg"
        download_file(url, filename)

    elif media_type == "VIDEO":
        url = media.get("media_url")
        filename = f"{timestamp}_{media_id}.mp4"
        download_file(url, filename)

    elif media_type == "CAROUSEL_ALBUM":
        children = get_carousel_children(media_id)
        for i, child in enumerate(children):
            child_url = child.get("media_url")
            ext = "mp4" if child.get("media_type") == "VIDEO" else "jpg"
            filename = f"{timestamp}_{media_id}_part{i+1}.{ext}"
            download_file(child_url, filename)


def main():
    print("دریافت لیست پست‌ها...")
    media_list = get_media_list(limit=20)
    print(f"{len(media_list)} پست پیدا شد.")
    for media in media_list:
        try:
            process_media(media)
        except Exception as e:
            print(f"خطا در پردازش {media.get('id')}: {e}")


if __name__ == "__main__":
    main()

توضیح خط‌به‌خط کد

این اسکریپت از سه بخش اصلی تشکیل شده است. تابع get_media_list با فراخوانی endpoint اصلی، لیست پست‌ها را همراه با نوع مدیا، لینک دانلود، کپشن و زمان انتشار دریافت می‌کند. تابع get_carousel_children برای پست‌هایی که چند عکس دارند (نوع CAROUSEL_ALBUM) فراخوانی می‌شود تا هر آیتم کاروسل جداگانه دانلود شود. تابع download_file هم با streaming (پردازش تکه‌تکه‌ی فایل) از مصرف بیش از حد حافظه جلوگیری می‌کند و برای فایل‌های ویدیویی سنگین مناسب است.

مدیریت خطاهای رایج API

در پروداکشن، خطاها اجتناب‌ناپذیر هستند. دو خطایی که بیشترین اوقات با آن‌ها روبه‌رو می‌شوید عبارت‌اند از خطای ۴۲۹ (Too Many Requests) که نشان می‌دهد به سقف ۲۰۰ درخواست در ساعت رسیده‌اید، و خطای ۱۹۰ (Invalid OAuth Token) که نشان‌دهنده‌ی منقضی شدن توکن است. در ادامه نحوه‌ی مدیریت این دو خطا را می‌بینید:


import time


def safe_api_call(url, params, max_retries=3):
    """فراخوانی API با مدیریت خطا و تلاش مجدد"""
    for attempt in range(max_retries):
        response = requests.get(url, params=params)

        if response.status_code == 200:
            return response.json()

        elif response.status_code == 429:
            # سقف نرخ درخواست رسیده - صبر و تلاش مجدد
            wait_time = 2 ** attempt  # 1, 2, 4 ثانیه
            print(f"محدودیت نرخ. صبر {wait_time} ثانیه...")
            time.sleep(wait_time)

        elif response.status_code == 190:
            # توکن منقضی شده
            raise Exception("توکن دسترسی منقضی شده. باید تجدید شود.")

        else:
            raise Exception(f"خطای API: {response.status_code} - {response.text}")

    raise Exception("تعداد تلاش‌های مجاز تمام شد.")

محدودیت‌های مهم که باید در طراحی سیستم رعایت کنید

اگر ابزار شما برای یک کسب‌وکار جدی طراحی می‌شود، این محدودیت‌ها را از همان ابتدا در معماری سیستم در نظر بگیرید، نه بعد از مواجهه با مشکل:

  • سقف ۲۰۰ درخواست در ساعت به ازای هر حساب (خطای درخواست‌های ناموفق هم از این سقف کسر می‌شود)
  • خرید API اینستاگرام فقط آخرین ۱۰ هزار پست را برمی‌گرداند (پست‌های قدیمی‌تر با pagination در دسترس‌اند)
  • لینک media_url که API برمی‌گرداند موقتی است و پس از مدتی منقضی می‌شود، پس باید بلافاصله دانلود شود
  • استوری‌ها در endpoint مجزا (stories/) هستند و ابزار باید این را جداگانه مدیریت کند
  • توکن دسترسی باید هر ۵۰ تا ۵۵ روز یک‌بار تجدید شود

استفاده از Webhook به‌جای Polling

اگر می‌خواهید ابزار شما به‌محض انتشار پست جدید، آن را دانلود کند، به‌جای بررسی مکرر API در فواصل زمانی مشخص (Polling)، از Webhook استفاده کنید. Webhook یعنی به Meta می‌گویید «هر وقت یک پست جدید منتشر شد، به سرور من اطلاع بده». این روش نه‌تنها خیلی بهینه‌تر است (درخواست‌های Webhook از سقف نرخ کسر نمی‌شوند)، بلکه نتیجه را هم سریع‌تر دریافت می‌کنید.

نکات امنیتی برای نگهداری توکن دسترسی

توکن دسترسی API شما به اندازه‌ی رمز عبور حساب‌تان حساس است. اگر این توکن لو برود، هر کسی می‌تواند به اطلاعات حساب اینستاگرام شما دسترسی پیدا کند. چند اصل مهم:

  1. هرگز توکن را مستقیم در کد (Hardcode) ننویسید.
  2. از متغیرهای محیطی (Environment Variables) یا سرویس‌های مدیریت راز مثل Vault استفاده کنید.
  3. توکن را هرگز در Git یا ابزارهای نسخه‌بندی ذخیره نکنید.
  4. در صورت مشکوک شدن به افشای توکن، فوری آن را در Meta Developer Portal باطل کنید.

نتیجه‌گیری

ساخت ابزار دانلود پست اینستاگرام با API رسمی Meta، گرچه در ابتدا به نظر پیچیده می‌رسد، اما بر پایه‌ای محکم و پایدار بنا می‌شود که هیچ ریسک مسدودشدن حساب یا قطع ناگهانی سرویس ندارد. با درک درست محدودیت‌های API یعنی سقف ۲۰۰ درخواست در ساعت، فقط دسترسی به حساب‌های تأییدشده، و مدیریت صحیح توکن می‌توانید یک ابزار حرفه‌ای و قابل اتکا بسازید.

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

سوالات متداول (FAQ)

۱. آیا می‌توان با API رسمی اینستاگرام پست‌های سایر حساب‌ها را دانلود کرد؟

خیر. API رسمی Graph اینستاگرام در ۲۰۲۶ فقط به اطلاعات حساب‌هایی که توسط کاربر از طریق OAuth تأیید شده‌اند دسترسی می‌دهد. دانلود پست‌های عمومی حساب‌های دیگر از طریق API رسمی ممکن نیست و نیازمند رویکردهای متفاوتی است.

۲. چرا لینک media_url که API برمی‌گرداند بعد از مدتی کار نمی‌کند؟

لینک media_url که از API دریافت می‌کنید یک URL موقت (CDN Signed URL) است که پس از مدت مشخصی منقضی می‌شود. به همین دلیل باید بلافاصله پس از دریافت لینک، فایل را دانلود کنید و آن را روی سرور خودتان ذخیره کنید.

۳. آیا ابزار دانلود می‌تواند استوری‌ها را هم ذخیره کند؟

بله، اما استوری‌ها در یک endpoint مجزا به نام stories/ قرار دارند و باید آن‌ها را جداگانه فراخوانی کنید. همچنین استوری‌ها بعد از ۲۴ ساعت از این endpoint حذف می‌شوند، پس اگر می‌خواهید آن‌ها را نگه دارید باید در همان بازه‌ی زمانی دانلود شوند.

۴. اگر در حین دانلود خطای ۴۲۹ گرفتم چه کار کنم؟

خطای ۴۲۹ یعنی به سقف ۲۰۰ درخواست در ساعت رسیده‌اید. این خطا موقتی است و بعد از رسیدن ساعت بعدی، دسترسی به‌صورت خودکار بازمی‌گردد. در کد خود، یک منطق Exponential Backoff پیاده‌سازی کنید که با هر بار مواجهه با این خطا، مدت بیشتری صبر کند.

۵. آیا API رسمی اینستاگرام برای استفاده هزینه دارد؟

دسترسی به Instagram Graph API خودش رایگان است و Meta هیچ هزینه‌ای به ازای هر درخواست دریافت نمی‌کند. هزینه‌ی اصلی، زمان توسعه برای دریافت تأییدیه‌ی Meta App Review، مدیریت توکن‌ها، و زیرساخت سرور برای اجرای ابزار است.