Рубрики
Без рубрики

Разобедренная цензура бот строит бот, чтобы отфильтровать ругательства

Теперь, когда прошло 7 лет с тех пор, как начался карантин, я расширял свой ассортимент случайного дискора … Tagged с Discord, Python, Trie, Bot.

Теперь, когда прошло 7 лет с тех пор, как начался карантин, я расширял свой ассортимент случайных ботов. Моим последним экспериментом был бот, который может определить, имеет ли сообщение «плохое слово» в нем, и если да, удаляет сообщение, а затем скрепляет пользователя. Он также может определить, пытается ли пользователь обойти фильтр, используя «LeetsPeak». Это короткая статья о том, как работает этот бот.

Отказ от ответственности: этот бот (и следующая статья) вращается вокруг ругательства. Я буду говорить о ругательных словах в этой статье. Если это вас беспокоит, я бы порекомендовал не читать это. Лично у меня есть гораздо худшие вещи, о которых нужно беспокоиться в 2020 году.

БОТ ИНФОРМАЦИЯ

Если вы хотите установить бот на свой сервер Discord, просто Нажмите на эту ссылку Анкет К вашему сведению: Вы должны быть администратором на сервере Discord для его установки. Требуется Управление сообщениями разрешение, поскольку он удаляет сообщения плохими словами. Если вы хотите взглянуть на бота, весь код доступен Здесь, на GitHub Анкет Если у вас есть какие -либо запросы или ошибки, которые вы можете сообщить, вы можете сообщить о проблеме Здесь, на GitHub Или вы можете связаться со мной в Твиттере, @nldoty Анкет

Построение бота

При строительстве этого бота было 4 области, на которых я сосредоточился в разработке, и я сосредоточусь на каждой вскоре ниже.

Плохое список слов

Первая проблема заключается в составлении списка «плохих слов». В зависимости от того, что вам удобно, это может немного отличаться. Вы можете выбрать классику, 7 слов, которые вы не можете сказать Джорджем Карлин Анкет Другая статья, которую я нашел, была 26 Руководителя перечислен. Но я хотел быть максимально тщательным – поэтому я выбрал этот список 1300 слов из CMU Анкет При этом – было много слов, которые можно было рассматривать как «противоречивые», что я не чувствовал необходимости подвергать цензуре. Слова, такие как «республиканец» и «демократ». Я сузил его примерно до 1000 слов.

Структура данных

Затем нам нужен способ узнать, находятся ли какие -либо слова в сообщении в назначенном списке «плохих слов». Наивный подход будет поиском списка. Каждый раз, когда вы сталкиваетесь с словом, вы проверяете, существует ли оно в вашем списке «плохих слов». Проблема с этим подходом – сложность времени. Поиск списка Python ( x в списке ) – это На) где n это количество элементов в вашем списке. Если в вашем списке есть только 7 слов, это может быть приемлемо! Но с более чем тысячей слов это не сработает. К счастью, это почти учебник, используемый для Три Анкет

Так что, что такое тройка?

Три, или дерево префикса, представляет собой упорядоченную структуру, используемая для хранения динамической информации, которую можно искать. Это уникальный тип дерева, потому что в отличие от двоичного дерева, ни один узел в дереве не хранит ключ, который вы ищете – вместо этого сама ключ распределен.

Цель этого поста не в том, чтобы преподавать попытки: поэтому, если вы хотите прочитать больше, Этот гикс -гиксфордж Пост – отличный ресурс. Но вот TL; DR: Попытки состоят из узлов, и каждый узел содержит два свойства: Дети представляя узлы под узлом (обычно массив), и способ обозначить Конец слова. Реализация хранится Здесь , но код очень прост:

class TrieNode:
    _MAX_SIZE = 40

    def __init__(self):
        self.children = [None] * self._MAX_SIZE
        self.is_end_of_word = False

_Max_size 40, потому что это размер моего словаря: 'abcdefghijklmnopqrstuvwxyz12345670 (|@$ [!' Сама Три имеет две базовые функции: вставлять и Поиск Анкет Чтобы «построить» тройку, вы вставите все свои слова в структуру, а затем вы можете найти, чтобы увидеть, есть ли слово в вашем три. Вот пример изображения из Теория Программирования :

Поэтому, для моего примера, я хочу не только добавить все свои слова из списка моих плохих слов в свой Trie, но я также хотел добавить Leet Говорите Вариации, чтобы Три, чтобы поймать как можно больше нечестных слов.

Для этого я использую некоторую рекурсию, чтобы добавить дополнительные триеноды, когда я нахожу письмо с эквивалентом LeetSpeak – передавая оставшуюся часть букв в качестве слова для вставки, чтобы заполнить Trie со всеми возможностями. Код можно увидеть Здесь Анкет

Давайте посмотрим, как это будет работать на практике, со словом дерьмо Анкет Глядя на каждое отдельное письмо, S h i t : S имеет два эквивалента, $ и 5 h не имеет эквивалентов я имеет два эквивалента, | и ! t имеет один эквивалент, 7

Это в конечном итоге дает нам 18 различных вариантов для поиска: [дерьмо, шииг, sh | t, sh | 7, sh! t, sh! 7, $ Hit, $ Hi7, $ H | T, $ H | 7, $ H! T, $ H! 7, 5HIT, 5HI7 , 5H | T, 5H | 7, 5H! T, 5H! 7]

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

Чем больше слов вы ищете, тем больше времени вы будете экономить. Это красота использования Trie.

Интеграция разногласий

Код интеграции Discord можно увидеть Здесь и очень просто: он прослушивает все сообщения на сервере, анализирует сообщение в словах и ищет TRIE для каждого слова. Если в Trie найдено слово, бот удалит сообщение, а затем позор пользователю, используя случайный ассортимент стыряющих сообщений.

Единственная несколько интересная часть этого фрагмента кода – эта строка: Text.translate (str.maketrans (таблица))

Основная проблема, с которой я столкнулся с работой над ботом, – это определение вопроса: «Что такое слово? “Это была одна из самых сложных вещей для меня, чтобы решить. Когда люди набирают, они используют такие вещи, как пунктуация – запятые, периоды, тире, вы называете это. Типичный способ разделения строки на питоне использует .расколоть () , который сломает вещи по космосу. Однако, если у вас было предложение Мне нравится шпинат, кукуруза и бобы. Используя .расколоть () , ваш результат будет ['I', 'like', 'spinach,', 'Corn,', 'и', 'Beans. "]

В строительство своего трикотажа я не включаю пунктуацию, как периоды и запятые. Так что, если вы написали предложение «Заткнись, глупый, ублюдок». .split () разорвет это как [«Заткнись», «вверх», «ты», «глупый», «черт возьми». ] И моя Три будет пропустить слово Подонок Потому что есть период как часть слова , так что я бы не увидел is_end_of_word в правой точке.

Чтобы избежать этого, я использую string.translate Анкет Используя определенный словарь, он отображает ключи от их соответствующих значений – в моем случае я сопоставляю всех общих символов, которые не являются частью моего Trie LeetsPeak, чтобы Нет Анкет Это решило довольно много моих проблем, но, очевидно, не все из них.

Последняя серьезная проблема, которую я имею, нелегко решить. Действительно простой способ обойти бота – использовать пространства в середине слова – вместо дерьмо , просто напишите sh это Анкет Бот видит это как два слова, и не соединяется с этим без пространства, было сделано ругательство. Я мог бы добавить пространства к Три на каждом уровне, но как в конечном итоге будут разделены слова? Как я мог передать слова Три, чтобы дерьмо , штрих , а также это все проверяются? Это становится все более и более сложным, чем больше слов/пространств, которое у вас есть. Вы можете искать все возможные итерации с помощью своего рода окна, но затем вы сталкиваетесь с серьезными проблемами скорости. Лучшим ответом будет какой -то способ для программы, чтобы узнать, что фургонный CK на самом деле просто одно слово, но О, HM следует рассматривать как два слова. Я думаю, что эта проблема лучше всего объясняется с помощью этот XKCD Comic :

Докеризация

Наконец, мне нравится построить свои боты раздора в контейнеры Docker. Это просто делает развертывание намного проще. И Dockerfile для этого очень просто:

# set base image (host OS)
FROM python:3.7.7

# set the working directory in the container
WORKDIR /code

# copy the dependencies file to the working directory
COPY requirements.txt .

# install dependencies
RUN pip install -r requirements.txt

# copy the content of the local src directory to the working directory
COPY src/ .

# command to run on container start
CMD [ "python", "./main.py" ]

Затем построение контейнера в верхнем каталоге так же просто, как Docker Build -t PottyBot. И запуск контейнера просто Docker Run Pottybot

Вот и все! Если вы хотите запустить бот самостоятельно, это довольно прямолинейно. Следуйте вместе с это руководство создать бота в Разработчик Discord Portal Анкет Как только у вас есть токен, создайте .env Файл в SRC/ Папка с одной строкой: Discord_token = 'your_token_here'

Затем постройте и запустите контейнер Docker, и вы настроены! Если у вас есть какие -либо вопросы или комментарии, не стесняйтесь обратиться ко мне, и я рад помочь!

Оставайтесь в безопасности и здоровы!

Оригинал: “https://dev.to/nldoty/building-a-discord-bot-to-filter-out-swear-words-46h5”