EduVK

Материал из Поле цифровой дидактики

VK EDU

Автор: Башашкин Алексей

Группа: АДЭУ-221

Дисциплина: Работа с API социальных сетей и облачных сервисов

Статус проекта: Выполнен

Цель

Разработать веб-приложение для поиска, фильтрации и отображения образовательного контента из социальной сети VK с возможностью сохранения и удобного просмотра полезных материалов.

Задачи

  • изучить возможности VK API
  • реализовать получение данных из API (посты из сообществ и глобальный поиск)
  • разработать механизм фильтрации и обработки текстового контента
  • реализовать веб-интерфейс для отображения результатов

VK API

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

Методы представляют собой условные команды, которые соответствуют той или иной операции с базой данных — получению информации, записи или удалению. Например:

  • users.get — метод для получения информации о пользователе.
  • video.add — метод для добавления видео в список видео.
  • messages.delete — метод для удаления сообщений.

Для работы некоторых методов нужны права доступа к данным пользователя. Виды доступов:

  • Базовые — фамилия и имя, фото профиля, пол и дата рождения, а также почта по запросу.
  • Расширенные — номер телефона

Описание приложения

Приложение работает как “умный агрегатор” образовательного контента.

Пользователь вводит поисковый запрос (например, “Python” или “SQL”), после чего система:

  1. Отправляет запрос к VK API
    • получает посты из выбранных образовательных сообществ
    • выполняет глобальный поиск по социальной сети
  2. Выполняет обработку данных:
    • удаляет пустые и нерелевантные записи
    • сокращает текст постов
    • формирует ссылки на оригинальные публикации
    • преобразует дату в удобный формат
  3. Сортирует посты по популярности (количеству лайков)
  4. Отображает пользователю:
    • результаты поиска
    • блок “популярные посты”
    • сохранённые пользователем записи

Пользователь может:

  • перейти к оригинальному посту
  • сохранить интересный материал

Структура проекта

Интерфейс

Интерфейс

Код проекта

from flask import Flask, render_template, request, session, redirect, url_for
import requests
from datetime import datetime

app = Flask(__name__)
app.secret_key = "super_secret_key"

ACCESS_TOKEN = "access_token"
API_VERSION = "5.131"

# фильтрация групп
GROUP_IDS = [
    -54530371,
    -88815732,
    -60465354,
    -167073223,
    -200069708,
    -149279146
]

# ограничение количества символов в посте
def clean_text(text):
    text = text.strip().replace("\n", " ")
    if len(text) > 250:
        text = text[:250] + "..."
    return text

def format_date(timestamp):
    dt = datetime.fromtimestamp(timestamp)
    return dt.strftime("%d.%m.%Y %H:%M")

# получение ссылки на пост
def make_link(item):
    owner_id = item.get("owner_id")
    post_id = item.get("id")

    if not owner_id or not post_id:
        return None

    return f"https://vk.com/wall{owner_id}_{post_id}"

# получение постов
def fetch_posts(query=None):
    posts = []

    # 🔹 из групп
    for group_id in GROUP_IDS:
        url = "https://api.vk.com/method/wall.get"

        params = {
            "owner_id": group_id,
            "count": 10,
            "access_token": ACCESS_TOKEN,
            "v": API_VERSION
        }

        response = requests.get(url, params=params)
        data = response.json()

        if "response" not in data:
            continue

        for item in data["response"]["items"]:
            text = item.get("text", "")

            if not text:
                continue

            if query and query.lower() not in text.lower():
                continue

            link = make_link(item)
            if not link:
                continue

            posts.append({
                "text": clean_text(text),
                "likes": item["likes"]["count"],
                "date": format_date(item["date"]),
                "link": link
            })

    # глобальный поиск
    if query:
        url = "https://api.vk.com/method/newsfeed.search"

        params = {
            "q": query,
            "count": 20,
            "access_token": ACCESS_TOKEN,
            "v": API_VERSION
        }

        response = requests.get(url, params=params)
        data = response.json()

        if "response" in data:
            for item in data["response"]["items"]:
                text = item.get("text", "")

                if not text:
                    continue

                link = make_link(item)
                if not link:
                    continue

                posts.append({
                    "text": clean_text(text),
                    "likes": item["likes"]["count"],
                    "date": format_date(item["date"]),
                    "link": link
                })

    # удаление дубликатов
    unique_posts = {p["link"]: p for p in posts}.values()

    # сортировка постов по лайкам
    posts = sorted(unique_posts, key=lambda x: x["likes"], reverse=True)

    return posts[:15]


@app.route("/", methods=["GET", "POST"])
def index():
    posts = []
    popular_posts = []
    query = ""

    if request.method == "POST":
        query = request.form["query"]
        posts = fetch_posts(query)

    # популярные
    all_posts = fetch_posts("python")
    popular_posts = sorted(all_posts, key=lambda x: x["likes"], reverse=True)[:5]

    saved_posts = session.get("saved", [])

    return render_template(
        "index.html",
        posts=posts,
        popular_posts=popular_posts,
        saved_posts=saved_posts,
        query=query
    )


@app.route("/save")
def save_post():
    link = request.args.get("link")
    text = request.args.get("text")
    likes = request.args.get("likes")

    if "saved" not in session:
        session["saved"] = []

    session["saved"].append({
        "link": link,
        "text": text,
        "likes": likes
    })

    session.modified = True

    return redirect(url_for("index"))


if __name__ == "__main__":
    app.run(debug=True)

Вывод

В ходе выполнения проекта было разработано веб-приложение, демонстрирующее работу с внешним API и обработку данных в реальном времени.

  • использование API социальной сети позволяет получать актуальный контент без необходимости хранения данных локально
  • фильтрация и обработка информации существенно повышают её полезность для пользователя
  • даже простые механизмы сортировки (например, по лайкам) позволяют выделять более качественный контент
  • добавление пользовательских функций (сохранение постов, тёмная тема) улучшает удобство использования приложения
  • веб-технологии (Flask, HTML, CSS, JavaScript) позволяют быстро реализовать функциональный интерфейс