Карта друзей: различия между версиями
Нет описания правки |
Нет описания правки |
||
| Строка 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. Тема: «Карта друзей» — сбор и визуализация геолокаций из постов ВКонтакте | <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 | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<title>Карта друзей</title> | |||
<meta charset="utf-8" /> | |||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" /> | |||
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> | |||
<style> | |||
body { margin: 0; padding: 0; } | |||
#map { width: 100%; height: 100vh; } | |||
</style> | |||
</head> | |||
<body> | |||
<div id="map"></div> | |||
<script> | |||
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(` | |||
<b>${item.friend_name}</b><br> | |||
<i>${item.place}</i><br> | |||
${item.post_text}<br> | |||
<a href="${item.post_url}" target="_blank">Открыть пост</a> | |||
`); | |||
}); | |||
</script> | |||
</body> | |||
</html> | |||
</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 и создания интерактивных карт.
Задачи
- Изучить документацию VK API.
- Получить токен доступа для работы с данными.
- Написать скрипт на Python для сбора ID друзей и их публичных постов с геометками.
- Сохранить полученные координаты в формате JSON.
- Создать веб-страницу с картой (Leaflet) и нанести на нее точки.
- Опубликовать результат.
Технологии
- Языки: Python, JavaScript, HTML/CSS
- Библиотеки Python: requests, vk_api
- API: VK API, OpenStreetMap (через Leaflet)
- Хостинг: GitHub Pages (для карты)
Диаграмма работы приложения «Карта друзей»
Структура проекта

Файлы проекта: 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 через терминал:
Написала скрипт, который:
- Авторизуется по токену
- Получает список друзей
- Для каждого друга запрашивает последние 30 постов
- Проверяет наличие поля
geoв каждом посте - Сохраняет координаты, имя друга, текст поста и ссылку в JSON-файл
Результат: собрано 18 постов с геометками у 30 обработанных друзей.
Этап 4. Создание интерактивной карты
Создала HTML-страницу с картой на базе библиотеки Leaflet (OpenStreetMap). Написала JavaScript-код, который:
- Загружает данные из JSON-файла
- Разбирает координаты (формат "широта долгота")
- Добавляет маркеры на карту
- При клике на маркер показывает всплывающее окно с именем друга, местом и ссылкой на пост

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



Итог проекта
Создан работающий инструмент для сбора и визуализации геоданных из ВКонтакте
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
<!DOCTYPE html>
<html>
<head>
<title>Карта друзей</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { width: 100%; height: 100vh; }
</style>
</head>
<body>
<div id="map"></div>
<script>
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(`
<b>${item.friend_name}</b><br>
<i>${item.place}</i><br>
${item.post_text}<br>
<a href="${item.post_url}" target="_blank">Открыть пост</a>
`);
});
</script>
</body>
</html>
# requirements.txt
vk-api==5.107
requests==2.31.0



