Простий бот для сайту

Напевно, багато хто вже встиг помітити деякий нововведення на нашому сайті. Зараз я розповім, звідки пішли коріння, як працює бот і як наповнювалася база фраз. Зробити точно такого ж бота не складе труднощів, повірте.


коріння
Ідею додати на сайт бота підкинув благородний дон Virus-ON. так що все лаври йому.

Що ж потрібно для створення бота?
По-перше, база даних фраз - пам'ять бота, щоб він міг відповідати на повідомлення.
По-друге, деякий алгоритм вибору фраз - мозок бота, щоб він відповідав більш-менш в тему.


База даних. Частина 1
Волею випадку, довелося познайомитися з однією людиною, програмуючому під Android і моторошно ненавидить продукцію Apple. Однією з його розробок є VK iHA bot. исходники якого є на GitHub.
Сам додаток нам не цікаво, а ось база даних на перших порах була б вельми до речі. Її і візьмемо.

Формат бази такий:
повідомлення \ відповідь \ релевантність
приклад
привіт \ Привіт, радий тебе бачити! \ 3
як справи \ Справи відмінно! \ 2
я людина \ А я робот)) \ 2
Нам потрібно розпарсити цей файл, прибрати зайві посилання, імена, матюки (яких тут дуже багато) і зберегти все в іншому форматі, зрозумілому БД MySQL.
Скрипт на мові Scala:

import scala. collection. mutable. HashSet

import scala. io. Source

import java. io. File

object VkIHAbotDbExtractor # 123;

val filterWords = Array # 40; // тут перерахування відомих матюків для

def main # 40; args. Array # 91; String # 93; # 41; # 123;

var set = new HashSet # 91; Phrase # 93;

new File # 40; args # 40; 0 # 41; # 41;

filter # 40; _. endsWith # 40; ".bin" # 41; # 41;

foreach # 40; f => set = set ++ open # 40; f # 41; # 41;

override def toString # 40; # 41; = S "( '$ message', '$ answer'),"


У методі main ми перебираємо всі .bin файли в директорії і викликаємо для кожного такого файлу метод open. Метод open читає файл по рядках та перетворює рядок в клас Phrase. У класі Phrase ми розбиваємо рядок на повідомлення - відповідь.
По-суті спецсимволи для нашого бота - сміття. Йому не обов'язково знати, де у вхідному повідомленні стоїть кома, він повинен орієнтуватися за словами і цифрами. рядок

replaceAll # 40; "[^ \\ p \\ p] +". "" # 41;

якраз це і робить.
До слова, наш бот не розбирається, що перед ним: питання або твердження. Але він може зрозуміти це по спільним словами: що. де. як і т.д.

Після виконання скрипта, ми отримаємо такий висновок в SQL-форматі:

# 40; '0'. 'Гарне число ти написав.' # 41 ;.

# 40; '1'. 'У мене з цифрами проблеми.' # 41 ;.


Залишилося тільки створити таблицю в БД і залити дамп.

CREATE TABLE IF NOT EXISTS `bot` # 40;

`Id` int # 40; 11 # 41; NOT NULL AUTO_INCREMENT.

`Message` text NOT NULL.

`Answer` text NOT NULL.

PRIMARY KEY # 40; `id` # 41 ;.

FULLTEXT KEY `message` # 40; `message` # 41;

# 41; ENGINE = MyISAM DEFAULT CHARSET = utf8;

Алгоритм вибору фраз
Алгоритм простий. Користувач пише повідомлення, яке потім передається боту на обробку. Там ми прибираємо всі зайві символи з повідомлення і шукаємо в БД схожу запис. Знайшли одну - видаємо як відповідь. Знайшли кілька - вибираємо випадкову зі знайдених. Чи не знайшли нічого схожого - виводимо випадковий відповідь.

Тепер по порядку і з кодом.

1. Надійшло повідомлення, віддаємо його на фільтрацію:

private function filter # 40; $ message # 41; # 123;

$ Msg = mb_strtolower # 40; $ Message. 'UTF-8' # 41; ; // переводимо текст в нижній регістр

$ Msg = str_replace # 40; self. NAME. ','. ''. $ msg # 41; ; // прибираємо звернення до боту

$ Msg = preg_replace # 40; '# \ [C (. +?) \ [/ C \] # sui'. ''. $ msg # 41; ; // прибираємо цитату на випадок, якщо Magatino лінь натиснути Відповісти

$ Msg = preg_replace # 40; '/ [^ A-zа-я0-9] / u'. ''. $ msg # 41; ; // прибираємо всі спецсимволи

$ Msg = preg_replace # 40; '/ \ S + /'. ''. $ msg # 41; ; // кілька поспіль прогалин замінюємо на один

return trim # 40; $ msg # 41; ;


2. Вибираємо фразу за явною збігом:

SELECT `answer` FROM` bot` WHERE `message` =" привіт "ORDER BY RAND # 40; # 41; LIMIT 1


3. Якщо такий не знайшли, тоді скористаємося розумнішим варіантом:

SELECT `answer` FROM` bot`

WHERE MATCH # 40; `message` # 41; AGAINST # 40; "Привіт" IN NATURAL LANGUAGE MODE # 41;> 0

ORDER BY RAND # 40; # 41; LIMIT 1


4. Якщо і тут порожньо - вибираємо будь-яку відповідь з доступних:

SELECT `answer` FROM` bot` ORDER BY RAND # 40; # 41; LIMIT 1


Найцікавіший, ймовірно, другий запит. Він шукає збіги грунтуючись на природній мові. Ось відмінності:

Простий бот для сайту
Простий бот для сайту

Ось, власне, і весь мозок.
PHP клас Bot.class.php

Використовувати ось так (forum / say.php):

if # 40; $ Id == 226621 # 41; # 123; // id теми, де буде відповідати бот

$ Answer = Bot. byMessage # 40; $ msg # 41; -> getAnswer # 40; # 41; ;

`Text` = '". Mysql_real_escape_string # 40; $ Llogin. ','. $ answer # 41 ;. " '" # 41; ;

mysql_query # 40; "UPDATE` users` SET `lastdate` = '$ realtime' WHERE` id` = ' ". Bot. ID. " '" # 41; ;

База даних. Частина 2
Чотирьох тисяч повідомлень явно мало, потрібно поповнити базу чимось таким, що відповідає тематиці сайту. Парсити кожне повідомлення на форумі не кращий варіант - не ясно де питання, де відповідь. Але ось повідомлення, що містять цитату, нам цілком підходять. У них вже є питання і прям в тому ж повідомленні відповідь.

Спершу дістаємо з бази форуму всі повідомлення, що містять цитату:

SELECT `text` FROM` forum` WHERE `text` REGEXP '^ \\ [c (= | \]) *'


Потім зберігаємо дамп. У мене вийшов файл в 12 Мб, що містить 38 тисяч записів.
Тепер все це справа потрібно розпарсити. Знову кличемо на допомогу Scala.

import scala. collection. mutable. HashSet

import scala. io. Source

import java. io. File

Схожі статті