3 минут чтения
22 марта 2022 г.
Где поесть? Куда сходить? Ищем ответ на вопрос с помощью пары рекомендаций и скрипта Python
Поскольку наш блог придерживается технологий, аналитики и IT-тематики, то обсуждение политики мы здесь, естественно опустим. Однако, сложно не заметить, что многие сейчас целенаправленно или волей случая оказываются в незнакомых городах и странах. Или планируют переезд, или просто путешествуют. В любом случае, где бы вы ни оказались, всегда хочется выстроить быт, сходить на завтрак или выпить вкусный кофе. Если вам интересно, чем в этих вопросах может помочь наш скрипт и проверить его в действии – продолжайте читать.
Что мы придумали?
Итак, предположим, что вы оказались в незнакомом городе. У вас есть несколько рекомендаций от друзей или просто несколько проверенных мест, где вам вкусно и красиво.
Наш алгоритм может быстро увеличить этот список в несколько раз, дополнив его 5-10 рекомендациями того же качества или уровня. Звучит здорово, да?
Как мы это реализовали?
Мы все еще не умеем колдовать, поэтому решили прибегнуть к более простому способу — написать Python-скрипт для решения этой задачи.
Начинаем, как всегда, с подготовки. Самая важная шестеренка в нашем скрипте – Instagram API (деятельность социальной сети признана экстремистской и запрещена в Российской Федерации).
from instagrapi import Client
import time
import pandas as pd
Затем, подключаемся к API, чтобы приступить к обработке данных.
cl = Client()
cl.login(«username», «password»)
Наша задача реализуется двумя небольшими скриптами. Первый собирает и обрабатывает геометки из Instagram (деятельность этой социальной сети признана экстремистской и запрещена в Российской Федерации), а также находит людей, которые отмечали эти геометки на фотографиях. Мы знаем, что эти места наверняка нравятся не только нам и предполагаем, что мы нашли тех людей, которые разделяют наши вкусы и ценности. Поэтому, мы собираем все недавние геометки в их профиле и так получаем список рекомендаций. Затем, с помощью второго скрипта мы узнаем точные адреса этих мест в Яндекс.Картах, чтобы определиться с выбором.
Сбор и обработка данных
Начинаем работу. Для того чтобы получить список рекомендаций нам нужны три подходящих примера, например кофейни Санкт-Петербурга: Смена, ТЧК, Civil. Наш скрипт принимает на вход идентификаторы геоточек заведений.
Как их получить?
1. Переходим по ссылке в профиль заведения, например:
https://www.instagram.com/smenacafe/
2. Анализируем геометки в постах (считаем, что официальный профиль содержит правильные геометки)
3. Находим ссылку на геометку, например:
https://www.instagram.com/explore/locations/727911037416015/smenacafe/
4. Цифры в ссылке и есть идентификатор геоточки
727911037416015
После того как мы нашли геометки первичных рекомендаций, нам нужно найти тех пользователей, кто ходит в это заведение (= отмечает его на своих фотографиях). Для этого мы берем последние 150 отметок заведения.
Конечно, это должны быть реальные пользователи, а не бизнес-аккаунты, потому что там могут присутствовать рекламные интеграции, а мы в них не заинтересованы.
pk_place_ids = [541835746291313, 2103750586526340, 100059475]
print(‘Getting users started’)
# получаем пользователей, которые отметили заведение на фото
users = []
for i in pk_place_ids:
# получаем 150 последних постов с выбранной геометкой
medias = cl.location_medias_recent(i, amount=150)
for m in medias:
user_id = m.dict()[‘user’][‘pk’]
if not user_id in users:
users.append(user_id)
count_users = len(users)
print(f’Getting {count_users} users finished’)
print(‘Getting not business users started’)
# отбираем тех пользователей, чьи аккаунты не являются комерческими
users_not_business = []
for u in users:
try:
u_info = cl.user_info(u).dict()
if not u_info[‘is_business’]:
users_not_business.append(u)
except:
next
count_nb_users = len(users_not_business)
print(f’Getting {count_nb_users} not business users finished’)
print(‘Getting location started’)
Мы нашли людей, которые отмечали эти места у себя в профиле. Теперь мы собираем все места, которые отмечены в профилях этих людей и выводим эти места списком, сортируя по числу упоминаний.
# получаем места, которые посетил пользователь
locations = {}
end_cursor = None
for u in users_not_business:
# скрипт работает довольно медленно, поэтому анализируем только 100 последних постов пользователя
# посты получаем порциями 20 раз по 5 с сохранением курсора
for page in range(20):
u_medias, end_cursor = cl.user_medias_paginated(u, 5, end_cursor=end_cursor)
for m in u_medias:
# обернул в обработку исключений, т.к. иногда парсер падает
try:
# задержка для снижения чатсоты запросов в инстаграм
time.sleep(1)
# по идентификатору поста получаем данные поста (важно, что есть имя места, но нет его координат)
info = cl.media_info(m.dict()[‘pk’]).dict()
if ‘location’ in info:
loc_key = info[‘location’][‘pk’]
# вывод имени отмеченного места (для лога)
#print(info[‘location’][‘name’])
# если место встретилось первый раз, то узнаем его координаты
if loc_key not in locations:
# для того, чтобы узнать координаты, берем последний пост с такой геометкой
loc_data = cl.location_medias_recent(loc_key, amount=1)[0].dict()
lng=»
lat=»
if ‘location’ in loc_data:
lng=loc_data[‘location’][‘lng’]
lat=loc_data[‘location’][‘lat’]
locations[info[‘location’][‘pk’]] = [info[‘location’][‘name’],1,lng,lat]
else:
locations[info[‘location’][‘pk’]][1] = locations[info[‘location’][‘pk’]][1] + 1
# сохраняем результат в csv файл
ids = [i for i in locations]
names = [locations[i][0] for i in locations]
vizits = [locations[i][1] for i in locations]
lngs = [locations[i][2] for i in locations]
lats = [locations[i][3] for i in locations]
df = pd.DataFrame(
{‘id’: ids,
‘name’: names,
‘vizit’: vizits,
‘lng’: lngs,
‘lat’: lats
})
df.sort_values(‘vizit’, ascending=False).to_csv(‘places.csv’, index=False)
except:
next
count_locations = len(locations)
print(f’Getting {count_locations} location finished’)
Второй скрипт должен находить координаты новых рекомендаций в Яндекс.Картах.
# получим категории из справочника организаций сервиса Яндекс.Карты
import requests
# ключ API можно найти в кабинете разработчика
api_key = «—»
addrs = []
urls = []
cat1s = []
cat2s = []
cat3s = []
df = pd.read_csv(«places.csv»)
for i, row in df.iterrows():
time.sleep(1)
lng = row[‘lng’]
lat = row[‘lat’]
name = row[‘name’]
print(name)
req = f»https://search-maps.yandex.ru/v1/?text={name}&results=1&type=biz&lang=ru_RU&ll={lng},{lat}&spn=0.01,0.01&apikey={api_key}»
response = requests.get(req)
addr = »
url = »
cat1 = »
cat2 = »
cat3 = »
if response.status_code == 200:
# обернули в обработку исключений, т.к. иногда падает
try:
company_data = response.json()[‘features’][0][‘properties’][‘CompanyMetaData’]
addr = company_data[‘address’]
url = company_data[‘url’]
count_categories = len(company_data[‘Categories’])
# у организации может быть до 3 категорий, сохраняем их все
if count_categories > 0:
if count_categories == 1:
cat1 = company_data[‘Categories’][0][‘name’]
elif count_categories == 2:
cat1 = company_data[‘Categories’][0][‘name’]
cat2 = company_data[‘Categories’][1][‘name’]
elif count_categories == 3:
cat1 = company_data[‘Categories’][0][‘name’]
cat2 = company_data[‘Categories’][1][‘name’]
cat3 = company_data[‘Categories’][2][‘name’]
except:
pass
addrs.append(addr)
urls.append(url)
cat1s.append(cat1)
cat2s.append(cat2)
cat3s.append(cat3)
df[‘address’] = addrs
df[‘url’] = urls
df[‘cat1’] = cat1s
df[‘cat2’] = cat2s
df[‘cat3’] = cat3s
df.to_csv(‘places_24.csv’, index=False)
Результаты
Выпить кофе в Петербурге
Мы решили проверить, как работает скрипт на примере трех наших любимых кофеен в Петербурге. Получилось следующее:
Поужинать в Петербурге
Также мы протестировали наш скрипт, задав три рекомендации классных ресторанов Питера: Chang, Tiger Lilly, Jack and Chan.
Ограничения скрипта
1. Скрипт сбора данных работает недостаточно быстро (примерно 100 геоточек в час).
2. У геоточек может быть несколько дублей. Бывают геоточки с одинаковыми названиями, но отличающимися по координатам. Если честно, то по сути в геоточках просто хаос. Поэтому остается много ручной работы на этапе обработки и получения результатов.
3. Яндекс отдает данные хорошо: база организаций очень большая, но для большинства объектов заполнена не одна, а целых три категории. У кафе может быть первая категория бар, затем кафе, затем ресторан. В общем, приходится опять же проверять многое вручную.
4. Сделать единую процедуру пока не очень получается.
Пока со скриптом можно работать в два этапа:
– Первый этап – получение данных из инстаграма (название, частота посещений, координаты) и затем полуавтоматическая чистка от ненужных объектов + объединение дублей (это важно, так как бесплатная квота Яндекс.Карт – 500 запросов в день),
– Второй этап – получение из Яндекс.Карт категорий, адреса, сайта и затем ручная сверка категорий и выбор наиболее точной категории из трех.
[ Рекомендации ]
Читайте также
1 минута чтения
8 октября 2020
[ Связаться ]
Давайте раскроем потенциал вашего бизнеса вместе
Заполните форму на бесплатную консультацию