Борьба со спамом, если капча не помогает

Предыстория… Есть у меня один сайтик, и там есть гостевая книга, туда постоянно лезет спам. Спамеров (ботов или людей) капча не останавливала.

ВНИМАНИЕ.
Содержимое данной статьи морально устарело но сохранено для академических целей.

Хотя я и ставил их штук 5 разных, да еще и подключался к сервису автоматической генерации капчи. Исходом стало введение премодерации которая клиента не обрадовала. Какая разница чистить на форуме или в админ панели, сказал он мне. Некоторое время мне понадобилось что бы придумать что то еще чем можно уберечь сайт от нашествия спам ботов. Мною были прочитаны десятки статей по этому поводу и в итоге я нашел вот эту статью под названием Построение эффективной Анти-Спам системы. Ссылка на исходники была мертвая и по моей просьбе автор выслал мне их. Меня постигло небольшое огорчение. исходники были на C… Недолго думая я решил переписать на php, о чем и будет рассказано в этой статье.
Для тех кто ленится почитать исходную статью я немного расскажу о теории.

Теория

После отправки сообщения система проверяет его и выставляет баллы, если в конце получилось 1 или больше то сообщение публикуется, если получилось 0 то сообщение помечается как спам и публикуется. Если меньше нуля то сообщение заведомо является спамом.

В своем скрипте я не стал реализовывать все правила, а лишь некоторые из них.

Правила

ПравилоЗначениябаллы
Количество ссылок в сообщении≥2-1 за каждую
<2+1
Длина сообщения>20 символов и без ссылок+2
<20-1
Ключевые словаВиагра, молоденькие и т.д. по словарю-1 за каждую
BB теги[url] и [link]-1 за каждый

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

Исходный код

Что бы было проще проверять я сделал немного не так как было у автора статьи на хабре. А именно или спам или нет. За проверку отвечает функция которая отвечает false или true в зависимости от результата проверки.

function spam_filter($message) {
  $points = '0'; # начальное значение балов

  # присваиваем баллы за количество ссылок
  preg_match_all('/(http).?(:\/)/', $message, $out);
  $count_link ='0';
  foreach($out['0'] as $val) {
    $count_link++;
  }
  if ($count_link >= '2') {
    $points = $points - $count_link;
  } else {
    $points = $points + '1';
  }

  # присваиваем баллы за количество символов
  if (strlen($message) >= '20' and $count_link == '0') {
    $points = $points + '2';
  } else {
    $points = $points - '1';
  }

  # Проверка по фильтру
  $count_filter = '0';
  $query = mysql_query("SELECT `word` FROM `bad_word`;");
  while ($bad_word = mysql_fetch_row($query, MYSQL_NUM)) {
    preg_match_all('/'.$bad_word['0'].'/', $message, $out);
    foreach($out['0'] as $val) {
      $count_filter++;
    }
  }
  if ($count_filter > '0') {
    $points = $points - $count_filter;
  }

  # Поиск BB тегов
  $bb_count = '0';
  preg_match_all('/\[link/', $message, $out);
  foreach($out['0'] as $val) {
    $bb_count++;
  }
  preg_match_all('/\[url/', $message, $out);
  foreach($out['0'] as $val) {
    $bb_count++;
  }
  if ($bb_count > '0') {
    $points = $points - $bb_count;
  }

  # Вердикт
  if ($points >= '0') {
    return true;
  } else {
    return false;
  }
}

База данных

CREATE TABLE IF NOT EXISTS `bad_word` (
  `id_word` INT(4) NOT NULL AUTO_INCREMENT,
  `word` VARCHAR(255) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`id_word`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

В базе у нас хранится словарь плохих слов, его вы должны заполнить сами 😉

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Copyright © Programmer Weekdays | Powered by WordPress