Простой фильтр ленты VK по «плохим» словам и кем он может стать

    Привет, Хабр.

    Отступление:

    В этом посте вы не найдете той самой таблетки от всех болезней, но тут есть решение атомарной задачи, пускай и не совсем красивое. Цели этого поста получить больше фидбека, завязать обсуждение, заразить идеей, подтолкнуть. Хоть в данном случае речь идет о ВКонтакте, я бы попросил читателя абстрагироваться от этой соц. сети и посмотреть на это более глобально.


    Проблема:

    ВКонтакте есть возможность прятать единичные посты и блокировать показ постов от конкретных людей, групп и приложений. Но нельзя прятать посты с нежелательным содержимым.

    Опишу на простом примере:

    Я подписан на музыкальное сообщество и мне нравится периодически обновлять плейлисты, случайно узнавать новые группы и тд. Но мне не нравится видеть по несколько раз в день одни и те же рекламные посты. С репостами все просто: можно заблокировать источник. А как быть с рекламными постами от лица самого сообщества? Да, можно заблокировать посты сообщества в ленте и периодически заходить за новой музыкой, но тут теряется удобство пользования. Пример далеко не единственный. В ленте есть много сообществ и людей с интересными постами, но иногда, а временами частенько от них сыплется множество нежелательных постов.

    От проблемы к решению:

    Выбор пал на javascript. Немного экспериментов в консоли и код готов:

    function setWords() {
        words = prompt('Enter bad words and phrases. Comma separated (,).',localStorage.getItem('bad_words'));
        if(typeof(words) == 'string') {
            localStorage.setItem('bad_words',words);
        }
    }
    
    function hunt() {
        if( ! localStorage.getItem('bad_words')) {
            setWords();
            return;
        }
        textArr = localStorage.getItem('shit_words').split(',');
        posts = document.getElementsByClassName('feed_row');
        for(ii =0; ii<posts.length; ii++) {
            for(ll = 0; ll<textArr.length; ll++) {
                if(posts[ii].innerText.search(textArr[ll].trim()) > 0) {
                    thepost = document.getElementsByClassName('feed_row')[ii].children[0];
                    idToDel = thepost.getAttribute('id').split('post')[1];
                    delElement = document.getElementById('post_delete'+idToDel);
                    if(delElement) {delElement.click();}
                    break;
                }
            }
        }
        setTimeout('hunt()',5000);
    };
    
    hunt();
    if( ! document.getElementById('vk_feed_cleaner')) {
        menuVK=document.getElementById('side_bar').children[0]; 
        a=document.createElement('a');   
        a.setAttribute('href','javascript:setWords();');
        a.innerText = 'Set Bad Words';
        li=document.createElement('li'); 
        li.setAttribute('id','vk_feed_cleaner');
        li.appendChild(a);
        menuVK.appendChild(li);
    }
    


    Принцип до безобразия прост:

    Запускаем в консоли скрипт.
    При первом запуске он попросит ввести «плохие» слова или фразы. (разделитель запятая)
    Сохраняет слова в localStorage.
    Каждые 5 секунд пробегаем по содержимому постов: HTML элементы с классом «feed_row»
    Если в тексте элемента найдено хотя бы 1 плохое слово, то программно кликаем на HTML элементе удаления поста.
    В боковое меню помещается ссылка: Set Bad Words, по клику на которую можно изменить список плохих слов.

    jsfiddle.net/U2r9k/7 — а тут есть ссылка, перетащив которую на панель закладок, можно активировать код по клику.

    Не оптимизировано? Деревянно? Не сексуально? Главное, что заработало, и моя проблема была решена. Очень надеюсь, что многим людям он поможет так же как и мне.

    Сразу же пошли в голове мысли об оптимизации процесса.

    Минусы очевидны:

    Скрипт требует запуска каждое открытие или перезагрузку страницы.
    Большие словари будут нагружать браузер.

    Возможные варианты решения этой проблемы:

    Создать расширения для браузеров.
    Создать офлайн приложение, которому дать доступ к своему аккаунту. Приложение будет 24 часа в сутки фильтровать ленту.

    Безусловно второй вариант лучше, т.к. одно приложение решает проблему кроссплатформености. Но первый вариант тоже имеет право на существование — родительский контроль.

    Если офлайн приложение может только фильтровать личную ленту пользователя, то расширение для браузера будет «ходить» вместе с пользователем. У меня есть дети, которые, пока еще не пользуются, но скоро будут пользоваться компьютером.

    Представим, что приложение может развиться до такого простенького сервиса, где будет онлайн база словарей/масок по категориям (например: вконтакте 18+, одноклассники реклама)
    И расширения для браузеров, поддерживающее несколько соц. сетей.
    Устанавливаете расширение и выбираете словари. Ребенок ищет видео, просматривает свои новости, чужие страницы, сообщества, а контент прогоняется через фильтр и нежелательные элементы прячутся/удаляются.
    Этакий аналог AdBlock.

    Существует еще одна проблема — дубликаты. Я говорю не о репостах, а о случаях когда один и тот же контент постится от лица конкретного сообщества/человека. Ситуация довольно частая. Быть может это приложение, сохраняющее этакий фингерпринт поста в базу «я это уже видел, больше можно не отображать». Часто посты просто копируются друг у друга, и очень редко контент переписывается. Кстати, с таким приложением будет решена проблема с повторяющимися рекламными постами в ленте.

    Интересны мнения хабровчан на этот счет.

    И напоследок опрос по теме.

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

    Всем добра.

    Only registered users can participate in poll. Log in, please.

    Нужен ли вам сторонний инструмент для фильтрации нежелательного контента в соц. сетях?

    • 11.8%Нет. Стараюсь бороться своими силами.75
    • 41.3%Нет. Меня это не тревожит.263
    • 3.6%Да. Офлайн приложение, имеющее доступ к моей ленте.23
    • 22.9%Да. Онлайн приложения и скрипты для браузеров.146
    • 20.4%Да. Оба средства хороши.130
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 20

      +6
      Да. Онлайн приложения либо дополнения/расширения для браузеров.
        +1
        Здорово!
        Кстати, похоже что скрипт чувствителен к регистру.
          +2
          В Twitter такой нужен — там с фильтрованием ленты сложнее.
            +5
            Проще сделать дополнение, например, для Greasemonkey
              +3
              Скрипт требует запуска каждое открытие или перезагрузку страницы.

              У ВК большая часть навигации сделана как ajax-навигация. И посты в ленте тоже динамически подгружаются. Чтобы не проверять каждые пять секунд страницу, можно на какой-либо элемент повесить обработчик по событию DOMSubtreeModified, либо использовать MutationObserver. Тогда по событию обновления содержимого элемента можно проверить тип страницы, и, если это новостная лента, то проводить фильтрацию.
                0
                Mutation events were deprecated, поэтому рекомендуется использовать mutation observers. Я в своем расширении для загрузки музыки из пресловутой соц. сети именно mutation observers использовал (но и у MO есть свои недостатки, однако это далеко не недостатки ME).
                  0
                  Можете про недостатки написать или ссылку? Вроде, там по МО не надо всю страницу обновлять, в этом и есть плюс.
                    0
                    В общих чертах можно ознакомиться тут.
                    Например я стокнлуся с тем, что при слежении за дочерними элементами иногда для первого появившегося элемента функция добавления для него дочернего элемента добавляла оный в конец списка всех элементов вмсето того чтобы оказываться в родительском как положено.
                +1
                Такая функция должна быть по умолчанию Вконтакте.
                Последние 2-3 года вконтакте превратился в откровенную помойку…
                  +3
                  А у вас есть такой же, только по тупым постам и репостам?
                    0
                    Ага, Роскомнадзор называется :)
                    +3
                    Реквестирую такой для постов «мой внутренний возраст».
                      +1
                      Как-то самому вводить все нежелательные слова долго да и лень. Вообще не ок.

                      А вот если реализовать его в виде байесовского классификатора, наподобие спам-фильтра, то будет интересно.

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

                        +1
                        Особенно радуют «псевдоголосовалки» каких-то говноигр. «Вы играете?
                        — Уже играю!
                        — Идите все сюда!»
                        Такой треш наверное не шибко сложно отсечь.
                        0
                        А еще бы скрипт для Статей. Не понимаю зачем мне статьи на украинском. Или из Комсомольской правды.
                          0
                          Интересно, но ведь уже есть реализации, например, к чему велосипед изобретать…
                            0
                            Посмотрите вот это расширение от deNULL, бывшего разработчика ВКонтакте.

                            Его функциональность даже несколько шире. Помимо фильтрации по подстрокам, позволяет ещё и репосты скрывать.
                              0
                              Реклама заколебала. Я пользуюсь соцсетями по делу и мне, конечно, очень интересно во время работы узнавать внезапно о распродаже дамских сумочек с 146% скидкой…
                                0
                                textArr = localStorage.getItem('shit_words').split(',');

                                Так «bad» или «shit»?
                                  0
                                  Ой. Конфуз Конфузыч. В первоначальной версии было «shit», решил подменить перед публикацией, видимо пропустил.

                                Only users with full accounts can post comments. Log in, please.