Как парсить Trump Truth Social: полное руководство на Python 2025

Что такое Truth Social и почему важно следить за постами Трампа

Truth Social — социальная сеть, запущенная Дональдом Трампом в феврале 2022 года после его блокировки в Twitter и Facebook. Платформа построена на открытом движке Mastodon и позиционируется как пространство для свободного слова без цензуры. После возвращения Трампа в Белый дом в январе 2025 года его посты в Truth Social приобрели статус фактически официальных заявлений администрации США.

Слова Трампа двигают рынки. Это не преувеличение и не журналистский штамп — это статистический факт, подтверждённый сотнями исследований. Анонс новых тарифов, упоминание конкретной компании, комментарий о торговых переговорах — всё это способно за считанные минуты изменить котировки акций, валютные курсы и цены на сырьё на несколько процентов. Для трейдеров, аналитиков и бизнесменов, работающих с американским рынком, мониторинг его публикаций является не просто полезной привычкой, а конкурентным преимуществом.

Ручное отслеживание постов — неэффективное решение. Трамп публикует в среднем 10–30 записей в день, и важная информация может появиться в любое время суток. Автоматизированный парсинг позволяет получать данные немедленно после публикации, хранить их в структурированном виде и настраивать мгновенные уведомления.

В этом руководстве мы разберём технические детали работы с API Truth Social: какие эндпоинты доступны, как написать рабочий Python-скрипт, как организовать хранение данных и настроить автоматические уведомления. Всё это — с реальными примерами кода, которые можно сразу использовать на практике.

Неофициальный API Truth Social: эндпоинты и лимиты

Truth Social не предоставляет официального публичного API для разработчиков. Однако, поскольку платформа использует Mastodon в качестве основы, многие API-эндпоинты Mastodon работают и для Truth Social. Базовый URL для запросов: https://truthsocial.com/api/v1/.

Основные эндпоинты, которые нас интересуют:

Лимиты запросов: приблизительно 300 запросов в час для неавторизованных пользователей и до 1000 запросов в час при наличии Bearer-токена. Превышение лимита возвращает HTTP 429 (Too Many Requests). Для мониторинга в реальном времени достаточно одного запроса каждые 30–60 секунд — это укладывается в лимиты с большим запасом.

Параметры пагинации работают через max_id и since_id: передавая since_id равным ID последнего известного поста, вы получаете только новые публикации, что минимизирует объём передаваемых данных. Параметр limit позволяет запросить до 40 постов за один запрос.

Авторизация осуществляется через OAuth 2.0. Для получения токена необходимо зарегистрировать приложение через /api/v1/apps или использовать токен от вашего аккаунта Truth Social, который можно найти в настройках профиля в разделе разработчика.

Python-скрипт для парсинга Truth Social

Рассмотрим готовый скрипт для мониторинга постов Трампа. Скрипт периодически обращается к API, проверяет наличие новых постов и сохраняет их в локальную базу данных.

Для начала установим необходимые зависимости:

pip install requests python-telegram-bot schedule

Основной модуль парсера:

import requests
import sqlite3
import json
import time
import logging
from datetime import datetime

# Конфигурация
BASE_URL = "https://truthsocial.com/api/v1"
TRUMP_HANDLE = "realDonaldTrump"
HEADERS = {
    "User-Agent": "Mozilla/5.0 (compatible; TrumpMonitor/1.0)",
    "Accept": "application/json",
    # "Authorization": "Bearer YOUR_TOKEN_HERE"  # раскомментировать для авторизации
}

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s - %(levelname)s - %(message)s")

def get_account_id(handle: str) -> str:
    """Получить числовой ID аккаунта по хэндлу."""
    url = f"{BASE_URL}/accounts/lookup"
    resp = requests.get(url, params={"acct": handle}, headers=HEADERS, timeout=10)
    resp.raise_for_status()
    return resp.json()["id"]

def fetch_new_posts(account_id: str, since_id: str = None) -> list:
    """Получить посты пользователя, опционально только новые."""
    url = f"{BASE_URL}/accounts/{account_id}/statuses"
    params = {"limit": 40, "exclude_replies": "false"}
    if since_id:
        params["since_id"] = since_id
    resp = requests.get(url, params=params, headers=HEADERS, timeout=10)
    if resp.status_code == 429:
        logging.warning("Rate limit превышен, ждём 60 секунд...")
        time.sleep(60)
        return []
    resp.raise_for_status()
    return resp.json()

def extract_text(post: dict) -> str:
    """Извлечь чистый текст из HTML-контента поста."""
    import re
    content = post.get("content", "")
    text = re.sub(r"<[^>]+>", " ", content)
    return " ".join(text.split())

def parse_post(post: dict) -> dict:
    """Нормализовать данные поста для сохранения."""
    return {
        "id": post["id"],
        "text": extract_text(post),
        "created_at": post["created_at"],
        "reblogs_count": post.get("reblogs_count", 0),
        "favourites_count": post.get("favourites_count", 0),
        "url": post.get("url", ""),
        "raw_json": json.dumps(post, ensure_ascii=False),
    }

Функция мониторинга с учётом последнего сохранённого ID:

def monitor_loop(db_path: str, account_id: str, interval: int = 60):
    """Основной цикл мониторинга новых постов."""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    cursor.execute("SELECT MAX(id) FROM posts")
    row = cursor.fetchone()
    last_id = row[0] if row and row[0] else None

    logging.info(f"Запуск мониторинга. Последний известный ID: {last_id}")

    while True:
        try:
            posts = fetch_new_posts(account_id, since_id=last_id)
            if posts:
                logging.info(f"Получено {len(posts)} новых постов")
                for post in reversed(posts):  # сохраняем в хронологическом порядке
                    parsed = parse_post(post)
                    save_post(conn, parsed)
                    last_id = parsed["id"]
                    # Здесь можно вызвать функцию уведомления
            else:
                logging.info("Новых постов нет")
        except requests.RequestException as e:
            logging.error(f"Ошибка запроса: {e}")
        except Exception as e:
            logging.error(f"Неожиданная ошибка: {e}")

        time.sleep(interval)

if __name__ == "__main__":
    db_path = "trump_posts.db"
    init_db(db_path)
    account_id = get_account_id(TRUMP_HANDLE)
    logging.info(f"ID аккаунта Трампа: {account_id}")
    monitor_loop(db_path, account_id, interval=30)

Хранение постов в базе данных

Для долгосрочного хранения постов оптимально использовать SQLite (для небольших проектов) или PostgreSQL (для продакшн-решений с несколькими пользователями). Ниже представлена схема таблицы и функции работы с базой данных.

def init_db(db_path: str):
    """Инициализировать базу данных и создать таблицы."""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS posts (
            id          TEXT PRIMARY KEY,
            text        TEXT NOT NULL,
            created_at  TEXT NOT NULL,
            reblogs     INTEGER DEFAULT 0,
            favourites  INTEGER DEFAULT 0,
            url         TEXT,
            raw_json    TEXT,
            saved_at    TEXT DEFAULT (datetime('now'))
        )
    """)
    cursor.execute("""
        CREATE INDEX IF NOT EXISTS idx_created_at ON posts(created_at)
    """)
    conn.commit()
    conn.close()
    logging.info(f"База данных инициализирована: {db_path}")

def save_post(conn: sqlite3.Connection, post: dict):
    """Сохранить пост в базу данных (игнорировать дубликаты)."""
    cursor = conn.cursor()
    cursor.execute("""
        INSERT OR IGNORE INTO posts
            (id, text, created_at, reblogs, favourites, url, raw_json)
        VALUES
            (:id, :text, :created_at, :reblogs_count,
             :favourites_count, :url, :raw_json)
    """, post)
    conn.commit()
    if cursor.rowcount > 0:
        logging.info(f"Сохранён пост {post['id']}: {post['text'][:80]}...")

Структура базы данных позволяет легко делать запросы для анализа: искать посты по ключевым словам, сортировать по виральности (количеству ретвитов), фильтровать по дате. Индекс на поле created_at ускоряет временные выборки.

Для крупных аналитических проектов стоит рассмотреть PostgreSQL с расширением pg_trgm для полнотекстового поиска, или Elasticsearch для более сложных аналитических сценариев. Оба варианта поддерживают горизонтальное масштабирование.

Настройка автоматических уведомлений

Самый удобный способ получать уведомления о новых постах Трампа — Telegram-бот. Настройка занимает около 10 минут:

  1. Создайте бота через @BotFather в Telegram, получите API-токен
  2. Узнайте ваш Chat ID через @userinfobot
  3. Добавьте токен и Chat ID в конфигурацию скрипта
import asyncio
from telegram import Bot

TELEGRAM_TOKEN = "YOUR_BOT_TOKEN"
CHAT_ID = "YOUR_CHAT_ID"

async def send_telegram_alert(post: dict):
    """Отправить уведомление о новом посте в Telegram."""
    bot = Bot(token=TELEGRAM_TOKEN)
    message = (
        f"🔔 *Новый пост Трампа*\n\n"
        f"{post['text'][:1000]}\n\n"
        f"🔁 {post['reblogs_count']} | ❤️ {post['favourites_count']}\n"
        f"🕐 {post['created_at'][:16]}\n"
        f"[Открыть пост]({post['url']})"
    )
    await bot.send_message(
        chat_id=CHAT_ID,
        text=message,
        parse_mode="Markdown",
        disable_web_page_preview=False
    )

def notify(post: dict):
    asyncio.run(send_telegram_alert(post))

Для фильтрации важных постов добавьте список ключевых слов: тарифы, санкции, торговля, Китай, Россия. Уведомления будут приходить только при наличии этих слов в тексте, что снижает информационный шум.

Правовые аспекты парсинга

Парсинг публичных веб-сайтов находится в правовой серой зоне во многих юрисдикциях. С одной стороны, посты политических деятелей в публичных социальных сетях являются общедоступной информацией. С другой — компании активно пытаются ограничить автоматизированный доступ к своим данным.

Ключевые принципы, которых стоит придерживаться: не перегружайте серверы (соблюдайте разумные интервалы между запросами), не нарушайте правила использования сервиса, не продавайте собранные данные третьим лицам, используйте данные только для личного анализа или некоммерческих целей. Решение Верховного суда США по делу hiQ Labs vs. LinkedIn (2022) подтвердило, что парсинг публично доступных данных не является нарушением Закона о компьютерном мошенничестве (CFAA).

Для российских пользователей важно учитывать, что обработка персональных данных граждан РФ регулируется Федеральным законом № 152-ФЗ «О персональных данных». Хранение собственных аналитических баз данных о публичных персонах в некоммерческих целях, как правило, не нарушает это законодательство.

Сравнение методов отслеживания постов Трампа

Метод Задержка Сложность Стоимость Надёжность
Ручной мониторинг 5–60 мин Нет Бесплатно Низкая
RSS-лента (если доступна) 1–5 мин Низкая Бесплатно Средняя
Python + неофициальный API 15–60 сек Средняя Бесплатно Высокая
TrumpBot API (trumpbot.online) 5–15 сек Низкая Бесплатно Очень высокая
Коммерческие сервисы мониторинга 1–10 сек Низкая $50–500/мес Очень высокая
Скрейпинг HTML-страницы 30–90 сек Высокая Бесплатно Низкая (ломается при обновлениях)

Часто задаваемые вопросы

Есть ли официальный API у Truth Social?

Официального публичного API у Truth Social нет. Однако платформа построена на основе Mastodon с открытым исходным кодом, и её API-эндпоинты совместимы с протоколом Mastodon. Базовый URL: https://truthsocial.com/api/v1/. Это позволяет получать данные без официальной документации.

Как получить посты Трампа в реальном времени?

Для получения постов в реальном времени используйте polling — периодические запросы к API Truth Social с интервалом 30–60 секунд. Метод since_id позволяет получать только новые посты, не запрашивая уже известные. Также можно настроить Telegram-бот для мгновенных push-уведомлений.

Какие библиотеки Python нужны для парсинга Truth Social?

Минимальный набор: requests для HTTP-запросов и sqlite3 (встроена в Python) для базы данных. Для уведомлений добавьте python-telegram-bot. Для планировщика задач — schedule или APScheduler. Всё устанавливается через pip.

Насколько быстро обновляются данные через API?

При интервале опроса 30 секунд вы получите пост в среднем через 15–20 секунд после его публикации Трампом. Задержка зависит от времени ответа серверов Truth Social (обычно 200–500 мс) и вашего интервала polling.

Можно ли парсить Truth Social без регистрации?

Да, часть публичных данных доступна без авторизации — в том числе публичные посты. Однако для стабильного доступа с более высоким лимитом запросов рекомендуется зарегистрировать аккаунт и использовать Bearer-токен. Анонимный лимит — около 300 запросов/час.

Как хранить посты Трампа для последующего анализа?

SQLite отлично подходит для личного использования и небольших проектов — никакой настройки сервера не нужно. Для продакшена с несколькими пользователями рассмотрите PostgreSQL. Сохраняйте ID поста, текст, дату, счётчики ретвитов и лайков, а также сырой JSON для будущего переиспользования.

Есть ли ограничения на количество запросов к API Truth Social?

Неофициальные данные указывают на лимит ~300 запросов в час для анонимных пользователей и ~1000 запросов в час для авторизованных. При превышении сервер возвращает HTTP 429. Один запрос каждые 30 секунд — это 120 запросов в час, что хорошо вписывается в лимиты.

Законно ли парсить Truth Social?

Парсинг публично доступных данных публичных персон в некоммерческих целях, как правило, законен. Суды США (дело hiQ vs. LinkedIn, 2022) подтвердили это в отношении CFAA. Главное — соблюдать разумные лимиты нагрузки на серверы и не нарушать Terms of Service в части коммерческого использования.

Как настроить уведомления в Telegram при новом посте Трампа?

1) Создайте бота через @BotFather, сохраните токен. 2) Узнайте ваш Chat ID через @userinfobot. 3) Вставьте токен и Chat ID в конфиг скрипта. 4) В цикле мониторинга вызывайте функцию отправки сообщения при появлении нового поста. Можно добавить фильтр по ключевым словам (тарифы, Китай, Россия).

Влияют ли посты Трампа на финансовые рынки?

Да, и значительно. Исследования показывают, что посты о тарифах и торговой политике вызывают движение S&P 500 на 0.3–2% в течение часа после публикации. Валютные пары (USD/CNY, USD/MXN) реагируют ещё острее. Для трейдеров, торгующих на новостях, задержка в получении информации в 30 секунд может означать разницу в прибыли или убытке.