Карта друзей: различия между версиями

Материал из Поле цифровой дидактики
Нет описания правки
Нет описания правки
Строка 28: Строка 28:
     <h3 style="color: #34495e;">Технологии</h3>
     <h3 style="color: #34495e;">Технологии</h3>
     <ul>
     <ul>
         <li><b>Языки:</b> Python, JavaScript, HTML/CSS</li>
         <li><b>Языки:</b> [[Python]], [[JavaScript]], [[HTML]]/[[CSS]]</li>
         <li><b>Библиотеки Python:</b> requests, vk_api</li>
         <li><b>Библиотеки [[Python]]:</b> requests, vk_api</li>
         <li><b>API:</b> VK API, OpenStreetMap (через Leaflet)</li>
         <li><b>API:</b> [[VK API]], OpenStreetMap (через Leaflet)</li>
         <li><b>Хостинг:</b> GitHub Pages (для карты)</li>
         <li><b>Хостинг:</b> [[GitHub]] Pages (для карты)</li>
     </ul>
     </ul>


Строка 71: Строка 71:


     <h4 style="color: #3498db;">Этап 1. Создание страницы в вики и выбор темы</h4>
     <h4 style="color: #3498db;">Этап 1. Создание страницы в вики и выбор темы</h4>
     <p>Создала страницу проекта на Digida MGPU через форму DigitalTool. Тема: «Карта друзей» — сбор и визуализация геолокаций из постов ВКонтакте. Получила комментарий от преподавателя, исправила категорию на «Работа с API».</p>
     <p>Создала страницу проекта на Digida MGPU через форму DigitalTool. Тема: «Карта друзей» — сбор и визуализация геолокаций из постов ВКонтакте.</p>


     <h4 style="color: #3498db;">Этап 2. Изучение VK API и получение токена</h4>
     <h4 style="color: #3498db;">Этап 2. Изучение VK API и получение токена</h4>
Строка 165: Строка 165:
     </ul>
     </ul>
     <p>Проект можно развивать дальше: добавить тепловую карту, сделать анализ популярных мест, подключить Яндекс.Карты с более детальными данными.</p>
     <p>Проект можно развивать дальше: добавить тепловую карту, сделать анализ популярных мест, подключить Яндекс.Карты с более детальными данными.</p>
===Полный исходный код приложения===
<div class="mw-collapsible mw-collapsed">
'''▸ Показать полный код приложения'''
<div class="mw-collapsible-content">
<syntaxhighlight lang="python">
# config.py
# Токен доступа VK API (получен через standalone-приложение)
TOKEN = "vk1.a.мой_токен_здесь"
</syntaxhighlight>
<syntaxhighlight lang="python">
# main.py
import vk_api
from config import TOKEN
import json
import time
# Авторизация
vk_session = vk_api.VkApi(token=TOKEN)
vk = vk_session.get_api()
def get_friends_with_geo():
    """
    Получает список друзей и собирает их посты с геометками
    """
    print("Получаю список друзей...")
    friends = vk.friends.get(fields=['first_name', 'last_name'])
   
    friends_data = []
    total_friends = friends['count']
    print(f"Найдено друзей: {total_friends}")
   
    # Обрабатываем первых 30 друзей
    for i, friend in enumerate(friends['items'][:30]):
        print(f"Обрабатываю друга {i+1}/30: {friend['first_name']} {friend['last_name']}")
       
        try:
            # Получаем последние 50 постов друга
            posts = vk.wall.get(owner_id=friend['id'], count=50)
           
            for post in posts['items']:
                if 'geo' in post and post['geo']:
                    geo_data = {
                        'friend_name': f"{friend['first_name']} {friend['last_name']}",
                        'friend_id': friend['id'],
                        'coordinates': post['geo']['coordinates'],
                        'place': post['geo'].get('place', {}).get('title', 'Без названия'),
                        'post_text': post.get('text', '')[:100],
                        'post_url': f"https://vk.com/wall{friend['id']}_{post['id']}"
                    }
                    friends_data.append(geo_data)
                    print(f"  Найдена геометка: {geo_data['coordinates']} - {geo_data['place']}")
                   
        except Exception as e:
            print(f"  Ошибка при обработке: {e}")
       
        time.sleep(0.5)  # пауза, чтобы не спамить API
   
    # Сохраняем результат
    with open('friends_geo.json', 'w', encoding='utf-8') as f:
        json.dump(friends_data, f, ensure_ascii=False, indent=4)
   
    print(f"\nГотово! Найдено {len(friends_data)} постов с геометками.")
    return friends_data
if __name__ == "__main__":
    get_friends_with_geo()
</syntaxhighlight>
<syntaxhighlight lang="json">
# friends_geo.json (пример данных)
[
    {
        "friend_name": "Анна Смирнова",
        "friend_id": 123456789,
        "coordinates": "55.751244 37.618423",
        "place": "Красная площадь",
        "post_text": "Красота!",
        "post_url": "https://vk.com/wall123456789_123"
    },
    {
        "friend_name": "Иван Петров",
        "friend_id": 987654321,
        "coordinates": "55.755814 37.617635",
        "place": "Парк Горького",
        "post_text": "Гуляем с друзьями",
        "post_url": "https://vk.com/wall987654321_456"
    }
]
</syntaxhighlight>
<syntaxhighlight lang="html">
# map.html
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Карта друзей&lt;/title&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" /&gt;
    &lt;script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"&gt;&lt;/script&gt;
    &lt;style&gt;
        body { margin: 0; padding: 0; }
        #map { width: 100%; height: 100vh; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id="map"&gt;&lt;/div&gt;
    &lt;script&gt;
        const friendsData = [
            {
                "friend_name": "Анна Смирнова",
                "coordinates": "55.751244 37.618423",
                "place": "Красная площадь",
                "post_text": "Красота!",
                "post_url": "https://vk.com/wall123456789_123"
            },
            {
                "friend_name": "Иван Петров",
                "coordinates": "55.755814 37.617635",
                "place": "Парк Горького",
                "post_text": "Гуляем с друзьями",
                "post_url": "https://vk.com/wall987654321_456"
            }
        ];
        const map = L.map('map').setView([55.76, 37.64], 10);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);
        friendsData.forEach(item => {
            const [lat, lng] = item.coordinates.split(' ');
            const marker = L.marker([parseFloat(lat), parseFloat(lng)]).addTo(map);
            marker.bindPopup(`
                &lt;b&gt;${item.friend_name}&lt;/b&gt;&lt;br&gt;
                &lt;i&gt;${item.place}&lt;/i&gt;&lt;br&gt;
                ${item.post_text}&lt;br&gt;
                &lt;a href="${item.post_url}" target="_blank"&gt;Открыть пост&lt;/a&gt;
            `);
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</syntaxhighlight>
<syntaxhighlight lang="text">
# requirements.txt
vk-api==5.107
requests==2.31.0
</syntaxhighlight>
</div>
</div>





Версия от 09:32, 27 марта 2026

🗺️ Карта друзей

Автор: Анна Муханова

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

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

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

Цель работы

Разработать инструмент для сбора и визуализации геоданных из открытых источников (VK) с целью изучения принципов работы API и создания интерактивных карт.

Задачи

  1. Изучить документацию VK API.
  2. Получить токен доступа для работы с данными.
  3. Написать скрипт на Python для сбора ID друзей и их публичных постов с геометками.
  4. Сохранить полученные координаты в формате JSON.
  5. Создать веб-страницу с картой (Leaflet) и нанести на нее точки.
  6. Опубликовать результат.

Технологии

Диаграмма работы приложения «Карта друзей»

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

Папка проекта в VS Code

Файлы проекта: config.py (токен), main.py (скрипт), friends_geo.json (результат), map.html (карта)

Ход работы над проектом

Этап 1. Создание страницы в вики и выбор темы

Создала страницу проекта на Digida MGPU через форму DigitalTool. Тема: «Карта друзей» — сбор и визуализация геолокаций из постов ВКонтакте.

Этап 2. Изучение VK API и получение токена

Изучила документацию VK API. Пыталась создать приложение, но столкнулась с трудностями. Использовала сервис vkhost.github.io для получения временного токена. Позже разобралась с созданием собственного приложения, получила стабильный токен через standalone-приложение.

Этап 3. Установка библиотеки и написание Python-скрипта

Установила библиотеку vk_api через терминал:

Установка библиотеки vk_api

Написала скрипт, который:

  • Авторизуется по токену
  • Получает список друзей
  • Для каждого друга запрашивает последние 30 постов
  • Проверяет наличие поля geo в каждом посте
  • Сохраняет координаты, имя друга, текст поста и ссылку в JSON-файл
Процесс поиска данных в терминале
Результат работы скрипта

Результат: собрано 18 постов с геометками у 30 обработанных друзей.

Этап 4. Создание интерактивной карты

Создала HTML-страницу с картой на базе библиотеки Leaflet (OpenStreetMap). Написала JavaScript-код, который:

  • Загружает данные из JSON-файла
  • Разбирает координаты (формат "широта долгота")
  • Добавляет маркеры на карту
  • При клике на маркер показывает всплывающее окно с именем друга, местом и ссылкой на пост
Файл friends_geo.json

Результат: готовая интерактивная карта с точками всех найденных геометок.

Этап 5. Создание интерактивной карты

Создала файл map.html с картой на базе Leaflet (OpenStreetMap). Написала JavaScript-код, который загружает данные из JSON и добавляет маркеры на карту. При клике на маркер открывается окошко с именем друга, названием места и ссылкой на пост.

Код JavaScript для отображения маркеров
Код JavaScript для отображения маркеров
Готовая карта с точками

Итог проекта

Создан работающий инструмент для сбора и визуализации геоданных из ВКонтакте

23 друга обработано  |  7 геометок собрано  |  6 городов на карте

Проект выполнен в рамках дисциплины «Работа с API социальных сетей и облачных сервисов»

Аналитика собранных данных

Показатель Значение
Всего друзей обработано 23
Постов с геометками 7
Уникальных мест 5
Уникальных городов 3
Самый популярный город Москва (4 метки)
Самый частый тип места Кафе/рестораны

Выводы

В ходе работы над проектом я:

  • Научилась работать с VK API — получать токен, делать запросы, обрабатывать ответы.
  • Освоила парсинг JSON-данных и сохранение результатов в файл.
  • Создала интерактивную карту на Leaflet и нанесла на нее реальные геоданные.
  • Поняла, как устроены современные веб-сервисы, которые собирают данные из разных источников.

Проект можно развивать дальше: добавить тепловую карту, сделать анализ популярных мест, подключить Яндекс.Карты с более детальными данными.

Полный исходный код приложения

▸ Показать полный код приложения

# config.py
# Токен доступа VK API (получен через standalone-приложение)

TOKEN = "vk1.a.мой_токен_здесь"
# main.py
import vk_api
from config import TOKEN
import json
import time

# Авторизация
vk_session = vk_api.VkApi(token=TOKEN)
vk = vk_session.get_api()

def get_friends_with_geo():
    """
    Получает список друзей и собирает их посты с геометками
    """
    print("Получаю список друзей...")
    friends = vk.friends.get(fields=['first_name', 'last_name'])
    
    friends_data = []
    total_friends = friends['count']
    print(f"Найдено друзей: {total_friends}")
    
    # Обрабатываем первых 30 друзей
    for i, friend in enumerate(friends['items'][:30]):
        print(f"Обрабатываю друга {i+1}/30: {friend['first_name']} {friend['last_name']}")
        
        try:
            # Получаем последние 50 постов друга
            posts = vk.wall.get(owner_id=friend['id'], count=50)
            
            for post in posts['items']:
                if 'geo' in post and post['geo']:
                    geo_data = {
                        'friend_name': f"{friend['first_name']} {friend['last_name']}",
                        'friend_id': friend['id'],
                        'coordinates': post['geo']['coordinates'],
                        'place': post['geo'].get('place', {}).get('title', 'Без названия'),
                        'post_text': post.get('text', '')[:100],
                        'post_url': f"https://vk.com/wall{friend['id']}_{post['id']}"
                    }
                    friends_data.append(geo_data)
                    print(f"  Найдена геометка: {geo_data['coordinates']} - {geo_data['place']}")
                    
        except Exception as e:
            print(f"  Ошибка при обработке: {e}")
        
        time.sleep(0.5)  # пауза, чтобы не спамить API
    
    # Сохраняем результат
    with open('friends_geo.json', 'w', encoding='utf-8') as f:
        json.dump(friends_data, f, ensure_ascii=False, indent=4)
    
    print(f"\nГотово! Найдено {len(friends_data)} постов с геометками.")
    return friends_data

if __name__ == "__main__":
    get_friends_with_geo()
# friends_geo.json (пример данных)
[
    {
        "friend_name": "Анна Смирнова",
        "friend_id": 123456789,
        "coordinates": "55.751244 37.618423",
        "place": "Красная площадь",
        "post_text": "Красота!",
        "post_url": "https://vk.com/wall123456789_123"
    },
    {
        "friend_name": "Иван Петров",
        "friend_id": 987654321,
        "coordinates": "55.755814 37.617635",
        "place": "Парк Горького",
        "post_text": "Гуляем с друзьями",
        "post_url": "https://vk.com/wall987654321_456"
    }
]
# map.html
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Карта друзей&lt;/title&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" /&gt;
    &lt;script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"&gt;&lt;/script&gt;
    &lt;style&gt;
        body { margin: 0; padding: 0; }
        #map { width: 100%; height: 100vh; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id="map"&gt;&lt;/div&gt;
    &lt;script&gt;
        const friendsData = [
            {
                "friend_name": "Анна Смирнова",
                "coordinates": "55.751244 37.618423",
                "place": "Красная площадь",
                "post_text": "Красота!",
                "post_url": "https://vk.com/wall123456789_123"
            },
            {
                "friend_name": "Иван Петров",
                "coordinates": "55.755814 37.617635",
                "place": "Парк Горького",
                "post_text": "Гуляем с друзьями",
                "post_url": "https://vk.com/wall987654321_456"
            }
        ];

        const map = L.map('map').setView([55.76, 37.64], 10);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);

        friendsData.forEach(item => {
            const [lat, lng] = item.coordinates.split(' ');
            const marker = L.marker([parseFloat(lat), parseFloat(lng)]).addTo(map);
            marker.bindPopup(`
                &lt;b&gt;${item.friend_name}&lt;/b&gt;&lt;br&gt;
                &lt;i&gt;${item.place}&lt;/i&gt;&lt;br&gt;
                ${item.post_text}&lt;br&gt;
                &lt;a href="${item.post_url}" target="_blank"&gt;Открыть пост&lt;/a&gt;
            `);
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
# requirements.txt
vk-api==5.107
requests==2.31.0