[Скрипт] Алиса и Википедия

Не требует установки программ или изменения файлов

Модераторы: immortal, newz20

Vladkos
Сообщения: 1
Зарегистрирован: Вс июл 31, 2016 7:21 pm
Благодарил (а): 0
Поблагодарили: 0

Re: [Скрипт] Алиса и Википедия

Сообщение Vladkos » Вс июл 31, 2016 7:28 pm

Добрый день, не поможете разобраться? Столкнулся с такой проблемой, настроил все как описано, но Алиса ничего не говорит, только пишет в чате и в правом верхнем углу. Пробовал изменить say($say,1); на 2 и 3, все равно молчит.


Разобрался, проверил ThisComputer.minMsgLevel 2 и во всех say выставил 2
Bauka7kzmz
Сообщения: 1
Зарегистрирован: Ср апр 05, 2017 6:35 am
Благодарил (а): 0
Поблагодарили: 0

Re: [Скрипт] Алиса и Википедия

Сообщение Bauka7kzmz » Чт апр 06, 2017 12:06 pm

Vladkos писал(а):Разобрался, проверил ThisComputer.minMsgLevel 2 и во всех say выставил 2

Подскажите пожалуйста где искать "ThisComputer.minMsgLevel 2" более подробно. Пропал голос((( Спасибо ;)
kas5858
Сообщения: 364
Зарегистрирован: Вс янв 15, 2017 5:34 pm
Откуда: Москва
Благодарил (а): 100 раз
Поблагодарили: 53 раза

Re: [Скрипт] Алиса и Википедия

Сообщение kas5858 » Чт апр 06, 2017 1:22 pm

Bauka7kzmz писал(а):
Vladkos писал(а):Разобрался, проверил ThisComputer.minMsgLevel 2 и во всех say выставил 2

Подскажите пожалуйста где искать "ThisComputer.minMsgLevel 2" более подробно. Пропал голос((( Спасибо ;)
Обьекты > Computer > ThisComputer > Свойства
Вложения
22.PNG
22.PNG (30.83 КБ) 8056 просмотров
Raspberry Pi3 - Broadlink - MegaD - Много датчиков - Камеры - Часы.
Изображение Connect
vitosmaxim
Сообщения: 18
Зарегистрирован: Вт фев 28, 2017 12:56 pm
Благодарил (а): 12 раз
Поблагодарили: 0

Re: [Скрипт] Алиса и Википедия

Сообщение vitosmaxim » Сб ноя 11, 2017 10:39 pm

всё работает спасибо но почемуто из запроса берёт только четыре буквы что такое уголь отвечает угол и тд так получается неверные ответы как ето исправить
mmf16
Сообщения: 2
Зарегистрирован: Вт ноя 21, 2017 5:03 pm
Благодарил (а): 0
Поблагодарили: 2 раза

Re: [Скрипт] Алиса и Википедия

Сообщение mmf16 » Вт ноя 21, 2017 5:08 pm

день добрый.вот еще пример.
ИМЯ шаблона что такое (\w*)






$keywords = preg_split("/[\s,]+/",$original);
$total=count($keywords);
for($i=0;$i<$total;$i++) {
$message_text=$message_text." \nСлово №".$i.": ".$keywords[$i];
}


// Получаем переменные из шаблона с помощь встроенных функций.
$total=count($matches);
$message_text="Вся строка с переменными: ".$matches[0] . "
Количество переменных: ".$total."
Переменная №1: ".$matches[1];

say("$matches[1],секунду,ищу по википедии ",2);

// Установка свойства объекта на основании полученной переменной
sg("Объект.Свойство",$matches[1]);
context_getuser();
context_clear();
context_activate(ID);


$zap="$matches[1]";
$zapurl=urlencode($zap);
$url='http://ru.wikipedia.org/w/api.php?actio ... inprop=url';
$answ=file_get_contents($url);
$xml = simplexml_load_string($answ);
$otvet=$xml->Section->Item->Description;
echo $otvet;
$otvet=iconv("UTF-8","CP1251//IGNORE",$otvet);
$otvet=iconv("CP1251","UTF-8",$otvet);
say($otvet,2);
За это сообщение автора mmf16 поблагодарили (всего 2):
scorp49 (Пн ноя 27, 2017 12:55 pm) • Svetлая (Пн май 07, 2018 12:55 am)
Рейтинг: 2.33%
VladPTZ
Сообщения: 395
Зарегистрирован: Вт май 31, 2016 6:56 pm
Откуда: Россия Карелия Петрозаводск
Благодарил (а): 95 раз
Поблагодарили: 57 раз

Re: [Скрипт] Алиса и Википедия

Сообщение VladPTZ » Чт фев 01, 2018 10:55 pm

Сейчас у кого нибудь работает это скрипт?
У меня на вопросы кто такая или что такое говорит что "неизвестная команда" либо "Я не знаю такого слова"
Может чего в api поменялось?
Сервер МД на x86 micro pc ssd + HDD, OC Debian, терминал Xiaomi Redmi note 7
Мои исходники для мд управляемых устройств https://github.com/vgamaev/ESPMDDEVICE
VladPTZ
Сообщения: 395
Зарегистрирован: Вт май 31, 2016 6:56 pm
Откуда: Россия Карелия Петрозаводск
Благодарил (а): 95 раз
Поблагодарили: 57 раз

Re: [Скрипт] Алиса и Википедия

Сообщение VladPTZ » Сб фев 03, 2018 12:36 am

Код: Выделить всё

$data = fopen('test.xml', 'w'); //открываем файл для записи
fputs($data, $result); //записываем результат выполнения
fclose($data); //закрываем
$file = 'test.xml'; //указываем файл
$data_xml = simplexml_load_file($file); //загружаем его и раскладываем на массив

say($data_xml);  //выводим в консоль содержимое файла
У меня файл test.xml пустой или не существует, в какой папке на машине с линукс он должен создаваться? Поиском по файлам я его не нашел, возможно у меня где то нет прав на его создания.
Сервер МД на x86 micro pc ssd + HDD, OC Debian, терминал Xiaomi Redmi note 7
Мои исходники для мд управляемых устройств https://github.com/vgamaev/ESPMDDEVICE
Dynai79
Сообщения: 5
Зарегистрирован: Сб фев 10, 2018 4:41 pm
Благодарил (а): 9 раз
Поблагодарили: 0

Re: [Скрипт] Алиса и Википедия

Сообщение Dynai79 » Вс фев 11, 2018 10:44 pm

Спасибо за скрипт есть два вопроса

1) Почему то плохо срабатывает на вопрос "Кто такой"
к примеру "кто такой Пушкин" - предлагает мне сказать Пушкин Александр Сергеевич, 5 раз сказал, она все повторяла что есть запрос "Пушкин Александр Сергеевич"

2) Можешь ли адаптировать этот сктипт под луркмор?
Mescaline писал(а):Доброго времени суток!
В одном из видео наблюдал, как Алиса во время демонстрации говорила "я могу дать ответы на вопросы "что такое" или "кто такой"", но на форуме не нашел (хотя, по правде говоря, не очень-то искал) примеров реализации. Поэтому понемногу решил разобраться сам.
Беглый поиск в гугле дал две интересные (на первый взгляд) ссылки:
http://www.ibm.com/developerworks/ru/li ... wikipedia/
http://habrahabr.ru/post/104480/
Но в первой статье используется отдельный фреймворк, поэтому с моим скудными знаниями не стал даже пытаться, а на Хабре статья датирована 2010 годом. В целом она дает общие представления, но там есть два нюанса:
1) С тех пор Википедия перешла на https
2) Параметр inprop больше не существует в текущей версии MediaWiki

Полный актуальный список запросов и параметров можно найти здесь.
Если коротко о главном: нам нужен запрос action с параметром opensearch, сам запрос поиска search, параметром которого является наше слово и format, параметром которого будет (в моем случае) xml.

В итоге запрос выглядит так:

Код: Выделить всё

'https://ru.wikipedia.org/w/api.php?action=opensearch&search='.$request.'&format=xml'
, где $request - наш запрос.
$request мы перехватываем стандартно $request = $matches[1];

У себя я создал шаблон поведения вида "что такое (.+)". Код:

Код: Выделить всё

//устанавливаем кодировки
header("Content-type: text/html;charset=utf-8");
mb_internal_encoding("UTF-8");

$word = $request = $matches[1]; //получаем искомое слово
$space_replace = preg_match_all("#\s#isu", $request, $s); //проверяем, есть ли пробелы в запросе
if ($space_replace === 1) { //если есть
    $request = preg_replace("#\s#", '_', $request); //меняем их на _
}

$url = 'https://ru.wikipedia.org/w/api.php?action=opensearch&search='.$request.'&format=xml'; //формируем запрос
$ch = curl_init(); //инициируем curl
curl_setopt($ch, CURLOPT_URL, $url); //передаем url
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //возвращаем результат в виде строки
curl_setopt($ch, CURLOPT_USERAGENT, 'MyBot/1.0 (http://www.mysite.com/)'); //имитируем браузер
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //отключаем проверку ssl-сертификата узла

$result = curl_exec($ch); //выполяем curl

$data = fopen('test.xml', 'w'); //открываем файл для записи
fputs($data, $result); //записываем результат выполнения
fclose($data); //закрываем
$file = 'test.xml'; //указываем файл
$data_xml = simplexml_load_file($file); //загружаем его и раскладываем на массив
$text = $text1 = $data_xml->Section[0]->Item[0]->Text[0]; //получаем первый найденный вариант
$description = $data_xml->Section[0]->Item[0]->Description[0]; //получаем определение слова 
$description = mb_convert_encoding($description, 'UTF-8', 'UTF-8'); //конвертируем utf-8 без bom в простой utf-8
if (empty($description)) { //если ничего не нашлось
    say ("Я не знаю такого слова.");
} elseif (!empty($description)) { //иначе
    $text = preg_replace("#ё#", 'е', $text); //меняем "ё" на "е"
    $text = mb_strtolower($text, 'utf-8'); //меняем регистр всех букв на нижний
        if ($word === $text) { //если первый результат равен введенному слову
            function utf8_str_split($str) { 
            // переводим каждый символ в массив строк
            $split=1; 
            $array = array(); 
           for ( $i=0; $i < strlen( $str ); ){  
            $value = ord($str[$i]); //возвращаем ASCII-код сиволов и проверяем их на корректность
            if($value > 127){ 
                if($value >= 192 && $value <= 223) 
                    $split=2; 
                elseif($value >= 224 && $value <= 239) 
                    $split=3; 
                elseif($value >= 240 && $value <= 247) 
                    $split=4; 
                }else{ 
                $split=1; 
                } 
            $key = NULL; 
            for ( $j = 0; $j < $split; $j++, $i++ ) { 
                $key .= $str[$i]; 
            } 
            array_push( $array, $key ); 
            } 
        return $array; 
           } 
/** 
 * Функция вырезки
 * @param <string> $str 
 * @return <string> 
 */ 
            function clearstr($str){ 
                $sru = 'ёйцукенгшщзхъфывапролджэячсмитьбю'; 
                $s1 = array_merge(utf8_str_split($sru), utf8_str_split(strtoupper($sru)), range('A', 'Z'), range('a','z'), range('0', '9'), array('&',' ','#',';','%','?',':','(',')','-','_','=','+','[',']',',','.','/','\\')); 
                $codes = array(); 
                for ($i=0; $i<count($s1); $i++){ 
                    $codes[] = ord($s1[$i]); 
                } 
                $str_s = utf8_str_split($str); 
                for ($i=0; $i<count($str_s); $i++){ 
                    if (!in_array(ord($str_s[$i]), $codes)){ 
                            $str = str_replace($str_s[$i], '', $str); 
                    } 
                } 
             return $str; 
            } 

        $res = clearstr($description); //удаляем спецсимволы
        $res = preg_replace("#ё#isu", 'е', $res); //меняем ё на е
        //делаем первую букву большой
        $first = mb_substr($word, 0,1, 'utf-8'); //возвращаем 1 букву искомой фразы
        $last = mb_substr($word,1); //возвращаем остальное
        $first = mb_strtoupper($first, 'utf-8'); //переводим первую букву в верхний регистр
        $last = mb_strtolower($last, "utf-8"); //все остальное - в нижний
        $word = $first.$last; //склеиваем

        $rep = $word .", это "; //искомое слово + фраза замены

        $tracking = preg_replace("#".$word."#isum", $rep, $res,1); //заменяем первое слово определения нашим словом поиска и замены
        $tracking = preg_replace("#\s\(.*?\)#isu", '', $tracking); //удаляем все остальные круглые скобки и их содержимое

        say($tracking);
            } elseif ($word != $text){ //если искомое слово не найдено в первом варианте
                $text2 = $data_xml->Section[0]->Item[1]->Text[0]; //получаем второе совпадение
                $text3 = $data_xml->Section[0]->Item[2]->Text[0]; //получаем третье совпадение
                $say = "По Вашему запросу совпадений не найдено. Похожие результаты: ";
                //$say.=$text1 .", " .$text2 ." и " .$text3 .".";
                $say.=$text1; //первый похожий резальтат
                if ($text2 ==='') { //если во втором результате пусто
                    $say.="."; //ставим точку
                } else { //иначе
                    $say.= ", " .$text2; //ставим запятую и дописываем второй вариант
                        if ($text3 === '') { //если в третьем результате пусто
                            $say.="."; //ставим точку
                        } else { //иначе
                            $say.=" и " .$text3; //ставим запятую и дописываем третий вариант
                        }
                }
                say($say);
            }
}
В принципе я подписал все, что можно, но на всякий случай поясню принцип:
1) Перехватываем запрос
2) Проверяем, есть ли в запросе пробелы (если есть, меняем их на _). Это нужно для корректного формирования ссылки запроса
3) Инициируем cURL, устанавливаем две важные опции, без которых запрос по https не пройдет: USERAGENT и SSL_VERIFYPEER
4) Выполняем запрос, сохраняем результат локально в файл test.xml
5) Загружаем полученный xml и раскладываем его на массив
У меня не получилось заставить работать напрямую с результатом запроса, даже через new SimpleXMLElement, может я просто неправильно что-то делал, буду рад, если кто-то предложит менее "топорный" вариант обработки
6) Из всего xml получаем первый найденный результат и определение слова, конвертируем. У меня без конвертации символы отображались не корректно, notepad++ детектировал кодировку UTF-8 without BOM, поэтому возвращаем нормальный utf-8
7) Далее проверяем, есть ли вообще в xml хотя бы 1 строка Description. Если ее нет, значит в Википедии нет искомого слова, а значит Алиса говорит "Я не знаю такого слова"
8) Если есть:
- заменяем все "ё" на "е" в значении поля Text (нужно для сравнения введенного нами запроса и находящегося в xml)
- переводим слово из поля Text в нижний регистр (также для сравнения)
- сравниваем слово из нашего запроса и возвращенным значением Text
- если они идентичны, значит поиск удался и запускаются функции удаления спецсимволов
Все дело в том, что в Википедии используются специальные символы повсеместно - начиная от букв с ударениями и заканчивая дефисами. Код функций был взят отсюда, за что автору большое спасибо. Цикл возвращает ASCII-код каждого символа и сравнивает полученное значение, после чего удаляет все, что попадает под критерии поиска.
- меняем "ё" на "е" в определении искомого слова
- делаем первую букву нашего запроса большой (т.е., если Вы ввели в запрос "что такое берёза", на данном этапе слово "берёза" будет выглядеть как "Береза"). Это нужно для подстановки в ответ Алисы
- далее берем наше слово и подставляем после него ", это ". Так как дефис наши функции выше удалили как спецсимвол, нам нужно что-то, чтобы сделать эмоциональную паузу между словом и его определением. Я использую запятую и слово "это"
- заменяем первое слово определения (это слово, которое мы искали, с него начинается любое определение) нашей конструкцией
- удаляем все круглые скобки вместе с их содержимым (часто в скобках на Википедии пишут различные сокращения, формулы и прочий текст, который Алиса без нашей помощи корректно интерпретировать не сможет, поэтому я просто удаляю все в них)
- говорим получившуюся фразу
Приведу пример. Исходный запрос "что такое береза" возвращает (в "сыром" виде) вот такое определение:
Берёза (лат. Betula) — род листопадных деревьев и кустарников семейства Берёзовые (Betulaceae). Берёза широко распространена в Северном полушарии; на территории России принадлежит к числу наиболее распространённых древесных пород.
Благодаря обработке Алиса скажет:
"Береза, это род листопадных деревьев и кустарников семейства Березовые. Береза широко распространена в Северном полушарии; на территории России принадлежит к числу наиболее распространенных древесных пород."
- если искомое слово не найдено, получаем значение второго и третьего найденного результата
- если во втором результате пусто (т.е. найдено только 1 совпадение с искомым словом), то к фразе прибавляется значение первого Text, иначе после первого ставится запятая и дописывается второе
- аналогично с третьим результатом
В итоге, при частичном совпадении, Алиса выдаст 3 результата, похожих на наш запрос. Можно добавить и больше, на вкус и цвет :)
Например, при запросе "что такое кокос", Алиса скажет
"По Вашему запросу совпадений не найдено. Похожие результаты: Кокосовая пальма, Кокосовые острова и Кокосовое масло"

Вот в общем-то и все. Из того, что хочется реализовать еще:
1) Обработка запроса "кто такой (.+)". Алгоритм там будет отличаться из-за большого количества вариаций совпадений (например, по запросу "кто такой аль пачино", Алиса ничего не найдет, если применить этот алгоритм, из-за того, что Википедия возвращает в Text результат "Пачино, Аль" и строка уже не будет === введенному запросу, соответственно, условие поиска совпадения должно быть другим.
2) Обработка текста на предмет "трудных" для Алисы слов. Например, если в запросе будут римские цифры, Алиса (естественно) прочитает их не правильно, а учитывая, что после них идет какое-то слово, нужно еще и склонить это число в нужной форме.

Как обычно, поправки и советы приветствуются :)
*** Сообщение запрещено. ***
BET
Сообщения: 17
Зарегистрирован: Сб сен 26, 2015 6:03 pm
Благодарил (а): 17 раз
Поблагодарили: 0

Re: [Скрипт] Алиса и Википедия

Сообщение BET » Пт апр 06, 2018 5:02 pm

Здравствуйте.

Подскажите пожалуйста куда вставлять строку запроса
'https://ru.wikipedia.org/w/api.php?acti ... format=xml'

И куда вставлять основной код.

И второй вопрос можно ли настроить вопросы к википедии через модуль API.AI и как
Заранее всем буду благодарен.
fandaymon
Сообщения: 1553
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 39 раз
Поблагодарили: 574 раза

Re: [Скрипт] Алиса и Википедия

Сообщение fandaymon » Пт апр 06, 2018 5:22 pm

BET писал(а):
Пт апр 06, 2018 5:02 pm
Здравствуйте.

Подскажите пожалуйста куда вставлять строку запроса
'https://ru.wikipedia.org/w/api.php?acti ... format=xml'

И куда вставлять основной код.
Так написано же - я создал шаблон и в коде шаблона - вот такое... Линк уже есть в коде


И второй вопрос можно ли настроить вопр ... агодарен.

Можно! Или нельзя. Зависит от того, что такое через модуль API.AI....
Ответить