Мой телеграмм-канал: https://t.me/winc0de .
Привет. В свободное от работы время занимаюсь социальными проектами.
Мы с друзьями имеем достаточное количество «пабликов» в разных социальных сетях, что позволяет нам проводить различные эксперименты.
Встает острая проблема поиска актуального контента и новостей, которые можно будет публиковать.
В связи с этим возникла идея написать сервис, который бы собирал посты с самых популярных страниц и отображал их с помощью заданного фильтра.
Для первоначального теста я выбрал социальные сети ВКонтакте и Twitter.
Технологии
В первую очередь необходимо было определиться с хранилищем данных (кстати, сейчас количество хранимых записей превышает 2 миллиона) и эта цифра растет с каждым днем.Требования были следующие: очень частая вставка большого количества данных и быстрый выбор среди них.
Я уже слышал о базах данных Nosql и хотел их попробовать.
Я не буду описывать в статье сравнения баз данных, которые я проводил (mysql vs sqlite vs mongodb).
Для кеширования я выбрал кэширование памяти , позже объясню почему и в каких случаях.
Демон Python был написан как сборщик данных, который одновременно обновляет все группы из базы данных.
MongoDB и демон
Первым делом я написал прототип для сбора публикаций из групп.Я увидел несколько проблем:
- Вместимость склада
- Ограничения API
Поэтому нам пришлось поставить задачу отсеивать неинтересные и рекламные публикации.
Придумывать особо не пришлось, у меня всего 2 «таблицы»: группы И посты , в первом хранятся записи групп, которые необходимо проанализировать и обновить, а во втором — объем всех публикаций всех групп.
Сейчас я думаю, что это ненужное и даже плохое решение.
Лучше всего будет создать таблицу для каждой группы, это облегчит выбор и сортировку записей, хотя скорость не теряется даже при 2 миллионах.
Но этот подход должен упростить общую выборку для всех групп.
API
В тех случаях, когда вам необходима серверная обработка некоторых данных из социальной сети ВКонтакте, создается отдельное приложение, способное выдавать токен за любое действие.Для таких случаев я сохранил заметку со следующим адресом:
Вместо Идентификатор_приложения вставьте идентификатор вашего автономного приложения.http://oauth.vk.com/authorizeЭclient_id=APP_ID&redirect_uri=https://oauth.vk.com/blank.html&response_type=token&scope=groups,offline,photos,friends,wall
Сгенерированный токен позволяет получить доступ к указанным действиям в любое время.
Алгоритм работы парсера следующий: Берем идентификатор группы, циклически получаем все публикации, на каждой итерации отфильтровываем «плохие» посты и сохраняем их в базу данных.
Основная проблема — скорость.
API вконтакте позволяет выполнять 3 запроса в секунду.
1 запрос позволяет получить всего 100 публикаций – 300 публикаций в секунду.
В случае с парсером это не так уж и плохо: группу можно «слить» за одну минуту, но с обновлением будут проблемы.
Чем больше групп, тем дольше будет происходить обновление и, соответственно, результаты будут обновляться не так быстро.
Решением стало использование метода выполнения, который позволяет собирать API-запросы в кучу и выполнять их одновременно.
Таким образом, за один запрос я делаю 5 итераций и получаю 500 публикаций — 1500 в секунду, что даёт «слив» группы за ~13 секунд.
Вот как выглядит файл с кодом, который передается на выполнение: var groupId = -|replace_group_id|;
var startOffset = |replace_start_offset|;
var it = 0;
var offset = 0;
var walls = [];
while(it < 5)
{
var count = 100;
offset = startOffset + it * count;
walls = walls + [API.wall.get({"owner_id": groupId, "count" : count, "offset" : offset})];
it = it + 1;
}
return
{
"offset" : offset,
"walls" : walls
};
Код считывается в память, токены заменяются replace_group_id И replace_start_offset .
В результате я получаю массив публикаций, формат которых можно посмотреть на официальной странице API ВК.
vk.com/dev/wall.get Следующий этап – фильтр.
Я брал разные группы, просматривал публикации и придумывал возможные варианты скрининга.
Первое, что я решил сделать, это удалить все посты со ссылками на внешние страницы.
Это почти всегда реклама.
urls1 = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.
&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', text) urls2 = re.findall(ur"[-a-zA-Z0-9@:%.
_\+~#=]{2,256}\.
[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.
~#?&//=]*)", text)
if urls1 or urls2:
Теги: #JavaScript #mongodb #jQuery #python #vk #api #занимаюсь пиаром
-
Одевалки Принцессы Онлайн
19 Oct, 24 -
Pyqt: Простая Работа С Потоками
19 Oct, 24 -
Tagsistant: Семантическая Файловая Система
19 Oct, 24 -
Сегодня Ос Android Исполняется 5 Лет
19 Oct, 24