StoriesFly logo

Скачивание6 мин чтения

Как скачать сторис Instagram на Python без входа

Скачивание сторис Instagram на Python без логина: короткий скрипт на requests и API StoriesFly, повторный запуск не качает дубли, плюс строка для cron.

Команда StoriesFlyОпубликовано
Содержание
  1. Как скачать сторис Instagram на Python без входа в аккаунт?
  2. Что понадобится
  3. Полный скрипт
  4. Как запустить
  5. Что возвращает API
  6. Как скрипт работает с файлами
  7. Запуск каждые несколько часов
  8. Хайлайты
  9. Чем это лучше Instaloader и скриптов с логином
  10. Закрытые аккаунты
  11. Цена
  12. Правила использования
  13. Частые вопросы

Как скачать сторис Instagram на Python без входа в аккаунт?

Отправьте запрос к API сторис через requests, возьмите список stories из JSON-ответа и сохраните каждый media_url в файл. В API StoriesFly это один GET на /v1/user/stories с ключом в заголовке. Аккаунт Instagram, пароль и cookies не нужны. Скрипт ниже занимает около 60 строк и использует только requests и стандартную библиотеку.

StoriesFly — это наш API, поэтому примеры на нём. Тот же подход подойдёт для любого сервиса, который отдаёт ссылки на сторис. Статья про публичные аккаунты.

Что понадобится

  • Python 3.9 или новее
  • Пакет requests
  • API-ключ StoriesFly

Установка:

pip install requests

Ключ берётся на /developers/dashboard: войдите через Telegram. Новому аккаунту дают 100 бесплатных запросов, один раз на Telegram-аккаунт, этого хватит, чтобы попробовать всё из статьи. Ключ выглядит как sf_live_.... Документация на английском: /developers/docs, метод сторис описан на /developers/docs/user-stories.

Не храните ключ в коде. Скрипт читает его из переменной окружения STORIESFLY_KEY.

Полный скрипт

Сохраните как download_stories.py:

"""Download every story an Instagram account has up right now.

Usage:  STORIESFLY_KEY=sf_live_... python download_stories.py natgeo
"""
import os
import sys
from datetime import datetime, timezone
from pathlib import Path

import requests

API = "https://storiesfly.com/api/v1"
KEY = os.environ["STORIESFLY_KEY"]


def get_stories(username: str) -> list[dict]:
    r = requests.get(
        f"{API}/user/stories",
        params={"username": username},
        headers={"X-Api-Key": KEY},
        timeout=60,
    )
    if r.status_code != 200:
        # Every error is JSON: {"error": "...", "code": "..."}
        err = r.json()
        raise SystemExit(f"{r.status_code} {err['code']}: {err['error']}")
    print("Requests charged:", r.headers.get("X-Units-Charged"))
    return r.json()["stories"]


def download(url: str, path: Path) -> None:
    with requests.get(url, stream=True, timeout=120) as r:
        r.raise_for_status()
        with open(path, "wb") as f:
            for chunk in r.iter_content(chunk_size=1 << 16):
                f.write(chunk)


def main() -> None:
    username = sys.argv[1].lstrip("@")
    stories = get_stories(username)
    if not stories:
        print(f"@{username} has no stories right now.")
        return

    folder = Path("stories") / username
    folder.mkdir(parents=True, exist_ok=True)

    for story in stories:
        ext = "mp4" if story["media_type"] == "video" else "jpg"
        when = datetime.fromtimestamp(story["taken_at"], tz=timezone.utc)
        path = folder / f"{when:%Y-%m-%d_%H-%M-%S}_{story['id']}.{ext}"
        if path.exists():
            continue  # already saved on an earlier run
        download(story["media_url"], path)
        print("saved", path)


if __name__ == "__main__":
    main()

Как запустить

Задайте ключ и передайте имя пользователя, с @ или без:

export STORIESFLY_KEY=sf_live_your_key_here
python download_stories.py natgeo

Вывод выглядит так (значения примерные):

Requests charged: 1
saved stories/natgeo/2026-10-21_08-14-52_3412345678901234567.mp4
saved stories/natgeo/2026-10-21_09-02-10_3412345678901234999.jpg

Файлы попадают в stories/<username>/. Если активных сторис нет, скрипт напишет об этом и завершится.

Что возвращает API

GET /v1/user/stories?username=natgeo отвечает JSON с массивом stories. У каждого элемента такие поля:

ПолеЗначение
idИдентификатор сторис
media_typevideo или photo
media_urlСсылка на файл
taken_atUnix-время публикации
video_durationДлина в секундах, для видео

Пример элемента с выдуманными значениями:

{
  "id": "3412345678901234567",
  "media_type": "video",
  "media_url": "https://...",
  "taken_at": 1792570492,
  "video_duration": 12.4
}

Полная схема есть на странице метода и в OpenAPI-спецификации https://storiesfly.com/openapi.json.

Как скрипт работает с файлами

Видео или фото. Расширение зависит от media_type: mp4 для video, jpg для остального.

Имена файлов. Файл называется <дата>_<время>_<id>.<расширение>, например 2026-10-21_08-14-52_3412345678901234567.mp4. Время берётся из taken_at в UTC, поэтому файлы сортируются в порядке публикации. Id разводит две сторис, выложенные в одну секунду.

Повторный запуск пропускает сохранённое. Имя строится из данных, которые у сторис не меняются, поэтому одна и та же сторис всегда получает один и тот же путь. Если файл уже есть, скрипт идёт дальше без скачивания. Запускать его можно сколько угодно, скачиваются только новые сторис.

Качайте сразу. media_url ведёт на CDN Instagram, и такие ссылки со временем перестают работать. Скрипт скачивает файлы в том же запуске, где получил список. Не храните ссылки на потом.

Ошибки. Любая ошибка приходит как JSON {"error": "...", "code": "..."}. Скрипт печатает статус и code и останавливается. Частые коды: not_found (нет такого пользователя), private_account, unauthorized (неверный ключ), credits_exhausted и rate_limited (подождите, сколько указано в заголовке Retry-After, и повторите).

Запуск каждые несколько часов

Сторис исчезают через 24 часа после публикации. Чтобы вести архив, запускайте скрипт по расписанию. В Linux или macOS выполните crontab -e и добавьте строку:

0 */4 * * * cd /home/you/story-archive && STORIESFLY_KEY=sf_live_your_key_here /usr/bin/python3 download_stories.py natgeo >> run.log 2>&1

Она запускает скрипт в нулевую минуту каждого четвёртого часа. Один запуск стоит один запрос на аккаунт, скачивание файлов с CDN не считается, так что для одного аккаунта расписание раз в четыре часа даёт шесть запросов в сутки. Если аккаунтов несколько, пройдите по списку имён в shell-скрипте или оберните main() в цикл. Тогда добавьте паузу между аккаунтами, чтобы не упереться в лимит: 1 запрос в секунду до первого пополнения и 3 в секунду на уровне Start.

Хайлайты

Хайлайты остаются в профиле и не пропадают через сутки. Чтобы их сохранить, вызовите /v1/user/highlights?username=..., получите список хайлайтов, затем /v1/highlight с id нужного хайлайта, чтобы получить его элементы. Скачиваются они так же, как сторис. Подробности в документации: user highlights и highlight.

Чем это лучше Instaloader и скриптов с логином

Инструменты с входом в Instagram, например Instaloader, работают через сессию настоящего аккаунта. У этого есть цена. Аккаунт, с которого идут автоматические запросы, могут отправить на проверку (checkpoint) или заблокировать, а сессию и cookies приходится поддерживать самому. Если аккаунт вам дорог, это риск. С API сторис это не ваша забота: ваш скрипт превращается в обычный HTTP-запрос с ключом. Взамен вы платите за сервис и зависите от провайдера. Выбирайте то, что подходит вашему проекту.

Закрытые аккаунты

Сторис закрытых аккаунтов так скачать нельзя. API отвечает private_account (HTTP 403) и не отдаёт закрытый контент. Такие сторис видят только одобренные подписчики, и инструмент без входа обойти это не может.

Цена

Большинство вызовов считаются как один запрос. Оплата по факту с баланса в долларах, пополнить его можно криптой, включая TON и USDT. Ответы not_found и private_account тарифицируются как обычные данные. Сбои на стороне сервера (upstream_unavailable, internal_error) возвращаются. Актуальные цены на /developers/pricing.

Правила использования

Используйте скрипт для публичных данных и соблюдайте условия Instagram и законы вашей страны. Уважайте авторов: не публикуйте чужие сторис без разрешения.

Частые вопросы

Можно ли скачать сторис Instagram на Python без аккаунта?

Да. Скрипт обращается к API StoriesFly по ключу. Аккаунт Instagram или Facebook, логин и cookies не нужны.

Скачает ли скрипт одну сторис дважды при повторном запуске?

Нет. Файлы называются по времени публикации и id, а существующий путь скрипт пропускает. При повторе скачиваются только новые сторис.

Сколько запросов тратит один запуск?

Один запрос к /v1/user/stories на аккаунт. Скачивание файлов идёт с CDN Instagram и не считается. Стоимость вызова видна в заголовке X-Units-Charged.

Можно ли скачать сторис закрытого аккаунта?

Нет. API вернёт private_account и не отдаст контент. Работают только открытые аккаунты.

Зачем запускать скрипт по расписанию?

Сторис удаляются через 24 часа. Запуск раз в несколько часов сохраняет каждую сторис до того, как она исчезнет.

Работает ли скрипт с фото-сторис, а не только с видео?

Да. media_type бывает video или photo: видео сохраняется как .mp4, фото как .jpg.

Смотрите сторис незаметно

Откройте открытый профиль в Instagram, смотрите истории и сохраняйте их. Без аккаунта в Instagram и без установки — на сайте и прямо в Telegram.

Начать можно бесплатно. Тарифы