L o a d i n g
Создание модуля на основе нейронной сети для фильтрации спама в веб-формах на Django Сайты

Спам в веб-формах — это не просто раздражающий поток мусорных сообщений. Он засоряет почтовые ящики администраторов, перегружает системы уведомлений и может даже стать источником уязвимостей (например, через массовую отправку вредоносных ссылок). Традиционные методы борьбы, такие как CAPTCHA, регулярные выражения или чёрные списки слов, часто оказываются недостаточно гибкими: спамеры адаптируются, а легитимные пользователи страдают от неудобств.

Современный подход — использование нейронных сетей для анализа текста — позволяет добиться высокой точности в классификации "спам/не спам". В этой статье мы создадим модуль для Django-проекта, который:

  • Обнаруживает спам в формах с помощью обученной модели.
  • Блокирует отправку спам-сообщений на почту и их отображение в админке.
  • Легко интегрируется в существующий проект.

Шаг 1: Понимание задачи и подготовка данных

Проблема в деталях

Когда пользователь отправляет форму (например, комментарий или заявку), сообщение обычно:

  1. Сохраняется в базе данных.
  2. Отображается в админ-панели Django.
  3. Отправляется на email администратору или пользователю.

Если это спам, все эти действия становятся лишними и нежелательными. Наша цель — остановить процесс на этапе проверки формы, если текст классифицирован как спам.

Подготовка данных

Для обучения модели нужен датасет с примерами спама и нормальных сообщений. Можно использовать:

  • Открытые наборы данных, такие как "SMS Spam Collection" с Kaggle.
  • Собственные данные, если у вас уже есть история сообщений.

Пример предобработки текста:

import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords

nltk.download('punkt')
nltk.download('stopwords')

def preprocess_text(text):
    tokens = word_tokenize(text.lower())
    stop_words = set(stopwords.words('english'))  # или другой язык
    tokens = [word for word in tokens if word.isalnum() and word not in stop_words]
    return ' '.join(tokens)

Шаг 2: Обучение нейронной сети

Для простоты возьмём модель на основе LSTM (долгая краткосрочная память), которая хорошо справляется с классификацией текста. Используем TensorFlow.

Код обучения

import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# Пример данных
texts = ["buy cheap pills now", "hello, how are you", "free money click here"]
labels = [1, 0, 1]  # 1 - спам, 0 - не спам

# Токенизация
tokenizer = Tokenizer(num_words=5000)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
padded_sequences = pad_sequences(sequences, maxlen=50)

# Модель
model = Sequential([
    Embedding(input_dim=5000, output_dim=32, input_length=50),
    LSTM(64),
    Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(padded_sequences, np.array(labels), epochs=10)

# Сохранение
model.save('spam_detector.h5')
import pickle
with open('tokenizer.pkl', 'wb') as f:
    pickle.dump(tokenizer, f)

Это базовая модель. Для реального проекта можно использовать предобученные трансформеры (например, BERT) через библиотеку transformers.

Шаг 3: Интеграция в Django

Структура проекта

Добавим модуль spam_filter в Django-проект:

myproject/
├── spam_filter/
│   ├── __init__.py
│   ├── models.py
│   ├── forms.py
│   ├── utils.py
│   └── admin.py
├── myproject/
└── manage.py

Утилиты для проверки спама

В spam_filter/utils.py загрузим модель и создадим функцию классификации:

import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences
import pickle
from . import preprocess_text

# Загрузка модели и токенайзера
model = load_model('spam_detector.h5')
with open('tokenizer.pkl', 'rb') as f:
    tokenizer = pickle.load(f)

def is_spam(text):
    processed_text = preprocess_text(text)
    sequence = tokenizer.texts_to_sequences([processed_text])
    padded = pad_sequences(sequence, maxlen=50)
    prediction = model.predict(padded)[0][0]
    return prediction > 0.5  # Порог для спама

Форма с проверкой

В spam_filter/forms.py создадим форму, которая блокирует спам:

from django import forms
from .utils import is_spam

class CommentForm(forms.Form):
    text = forms.CharField(widget=forms.Textarea)

    def clean_text(self):
        text = self.cleaned_data['text']
        if is_spam(text):
            raise forms.ValidationError("Сообщение похоже на спам и не будет отправлено.")
        return text

Модель и админка

В spam_filter/models.py определим модель для сообщений:

from django.db import models

class Comment(models.Model):
    text = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    is_spam = models.BooleanField(default=False)

    def __str__(self):
        return self.text[:50]

В spam_filter/admin.py скроем спам из админки:

from django.contrib import admin
from .models import Comment

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
    list_display = ('text', 'created_at', 'is_spam')
    list_filter = ('is_spam',)
    
    def get_queryset(self, request):
        # Показываем только не-спам в админке
        return super().get_queryset(request).filter(is_spam=False)

Представление (view)

В spam_filter/views.py обработаем форму и заблокируем отправку email:

from django.shortcuts import render
from django.core.mail import send_mail
from .forms import CommentForm
from .models import Comment
from .utils import is_spam

def submit_comment(request):
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            text = form.cleaned_data['text']
            # Сохраняем только не-спам
            comment = Comment.objects.create(text=text, is_spam=is_spam(text))
            if not comment.is_spam:
                send_mail(
                    'Новый комментарий',
                    text,
                    'from@example.com',
                    ['admin@example.com'],
                    fail_silently=True,
                )
            return render(request, 'success.html')
    else:
        form = CommentForm()
    return render(request, 'comment_form.html', {'form': form})

Шаблоны

templates/comment_form.html:

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Отправить</button>
</form>

templates/success.html:

<h1>Спасибо! Ваш комментарий принят.</h1>

Шаг 4: Блокировка спама на уровне системы

  1. База данных: Спам сохраняется с флагом is_spam=True, но не отображается в админке благодаря фильтру в CommentAdmin.
  2. Email: Уведомления отправляются только для записей с is_spam=False.
  3. Пользовательский опыт: Если текст классифицирован как спам, пользователь видит ошибку формы и процесс останавливается.

Шаг 5: Оптимизация и улучшение

  • Производительность: Для больших проектов модель можно вынести на отдельный сервис (например, через FastAPI) и вызывать через API.
  • Обновление модели: Регулярно дообучайте модель на новых данных из вашей базы.
  • Логирование: Добавьте логи для анализа ложных срабатываний.

Заключение

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

Написать комментарий

Вы можете оставить комментарий автору статьи Обязательные поля помечены *