微信公众号最佳实践 ( 9.7)智能问答,关键词回复,中文分词

本文主要是介绍微信公众号最佳实践 ( 9.7)智能问答,关键词回复,中文分词,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

智能问答

前面我们使用的都是
  • 基于固定查询指令的回复,这样好处是内容格式统一,方便软件开发人员编写程序做出分析,回复精准的内容给用户
  • 但在生活中,人们问的内容很随意,甚至千差万别,这时,回复内容想要和用户的问题相匹配,就需要更智能的程序了

这里写图片描述

关键词回复

我们需先定一个数组,数组中键为关键词,值为对应的回复,当用户输入的文字能匹配到某个关键词时,则回复该关键词对应的内容,我们定义“电话”,“地址”,”微信”,三个关键词,将其作为数组中的键,然后定义相应的值,当用户发送的内容中包含相应的关键词名称时,则回复对应的内容。

代码如下所示:

 private function receiveText($object){$content = trim($object->Content);$keywords = array("电话" => "0755-87654321","地址" => "广东省深圳市南山区高新南一道飞亚达科技大厦(518057)","A型号手机" => "A产品报价 3000元,基本参数为:****,","B型号手机" => "A产品报价 4000元,基本参数为:****,","C型号手机" => "A产品报价 2000元,基本参数为:****,","微信" => "xxxxx");foreach ($keywords as $key=>$value){$contain = strchr($content, $key);if (!empty($contain)){$reply = $value;break;}}$result = $this->transmitText($object, $reply);return $result;}

中文分词

除了关键词回复之外,还可以使用中文分词来帮助我们实现智能回复。

中文分词指的是将一个汉字序列切分成一个个单独词。
分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。
我们知道在英文的行文中,单词之间是以空格作为自然分隔符的,而中文只有字、句、和段,能通过简单的分界符来简单划分,唯独词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一层上,中文要比英文复杂的多,困难的多。
中文分词就是要解决句子中词的划分问题,然后可以提取其中的关键词语进行搜索。
打个比方:“深圳天气怎么样”,这句话可分词为“深圳”,“天气”,“怎么样”三部分,因为它们代表不同词语类别的意思。

新浪云SEA提供了中文分词服务seaSegment,上述句子进行中文分词的代码如下所示

<?php$str="深圳天气怎么样";$seg = new SaeSegment();$ret = $seg->segment($str, 1);print_r($ret);
?>

代码运行后,结果如下所示:

Array ( [0] => Array ( [word] => 深圳 [word_tag] => 102 [index] => 0 ) [1] => Array ( [word] => 天气 [word_tag] => 95 [index] => 1 ) [2] => Array ( [word] => 怎么样 [word_tag] => 40 [index] => 2 ) 
)

上述结果中,

  • word表示分词
  • word_tag表示词性(102代表地点名词,95代表名词)
  • index表示词在句子中的位置索引

我们可以把分词功能写成函数,并且将名词作为分类标准,地点作为关键词组合成数组。

相应代码如下:

<?php
function sinasegment($str)
{$seg = new SaeSegment();$ret = $seg->segment($str, 1);if ($ret === false){return;}$category = "";$keyword = "";foreach ($ret as $key => $value) {if ($value["word_tag"] == 95){$category = $value["word"];}if ($value["word_tag"] == 102){$keyword = $value["word"];}}if (!empty($category) && !empty($keyword)){return array('category'=>$category, 'keyword'=>$keyword); }else{return;}
}
?>

根据获取的功能类别及关键字,我们可以做出根据地点来查询其相应的自动回复,比如天气预报和空气质量,在前面的章节中,我们提到了将语音识别结果并入文本消息结果的查询,基于这些,我们可以开发出非常智能的**语音识别搜索**及**文本搜索**功能.

相应代码如下:

 private function receiveVoice($object){$funcFlag = 0;if (isset($object->Recognition) && !empty($object->Recognition)){$content = strval($object->Recognition);include("segment.php");$result = sinasegment($content);if (is_array($result)){switch ($result['category']){case "天气":$url = "http://apix.sinaapp.com/weather/?appkey=trialuser&city=".urlencode($result['keyword']);$output = file_get_contents($url);$replyContent = json_decode($output, true);break;default:$replyContent = "还不支持这一功能:".$result['category'];break;}}else{$replyContent = "不能理解你的内容:".$content;}}else{$replyContent = "未开启语音识别功能";}if (is_array($replyContent)){$resultStr = $this->transmitNews($object, $replyContent);}else{$resultStr = $this->transmitText($object, $replyContent);}return $resultStr;}

segment.php

<?php
function sinasegment($str)
{$seg = new SaeSegment();$ret = $seg->segment($str, 1);if ($ret === false){return;}$category = "";$keyword = "";foreach ($ret as $key => $value) {if ($value["word_tag"] == 95){$category = $value["word"];}if ($value["word_tag"] == 102){$keyword = $value["word"];}}if (!empty($category) && !empty($keyword)){return array('category'=>$category, 'keyword'=>$keyword); }else{return;}
}
?>

关键词index.php运行图片:

这里写图片描述

关键词回复 index.php 整体代码如下:

<?php
/*CopyRight 2018 All Rights Reserved
*/define("TOKEN", "weixin");$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {$wechatObj->responseMsg();
}else{$wechatObj->valid();
}class wechatCallbackapiTest
{public function valid(){$echoStr = $_GET["echostr"];if($this->checkSignature()){echo $echoStr;exit;}}private function checkSignature(){$signature = $_GET["signature"];$timestamp = $_GET["timestamp"];$nonce = $_GET["nonce"];$token = TOKEN;$tmpArr = array($token, $timestamp, $nonce);sort($tmpArr, SORT_STRING);$tmpStr = implode( $tmpArr );$tmpStr = sha1( $tmpStr );if( $tmpStr == $signature ){return true;}else{return false;}}public function responseMsg(){$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];if (!empty($postStr)){$this->logger("R ".$postStr);$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);$RX_TYPE = trim($postObj->MsgType);switch ($RX_TYPE){case "event":$result = $this->receiveEvent($postObj);break;case "text":$result = $this->receiveText($postObj);break;default:$result = "other msg type: ".$RX_TYPE;break;}$this->logger("T ".$result);echo $result;}else {echo "";exit;}}private function receiveEvent($object){$content = "";switch ($object->Event){case "subscribe":$content = "欢迎关注 德强1012 ";$content .= isset($object->EventKey)?("\n来自二维码场景 ".$object->EventKey):"";break;case "unsubscribe":$content = "取消关注";break;}$result = $this->transmitText($object, $content);return $result;}private function receiveText($object){$content = trim($object->Content);$keywords = array("电话" => "0755-87654321","地址" => "广东省深圳市南山区高新南一道飞亚达科技大厦(518057)","A型号手机" => "A产品报价 3000元,基本参数为:****,","B型号手机" => "A产品报价 4000元,基本参数为:****,","C型号手机" => "A产品报价 2000元,基本参数为:****,","微信" => "xxxxx");foreach ($keywords as $key=>$value){$contain = strchr($content, $key);if (!empty($contain)){$reply = $value;break;}}$result = $this->transmitText($object, $reply);return $result;}private function transmitText($object, $content){$textTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>";$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);return $result;}private function transmitNews($object, $arr_item){if(!is_array($arr_item))return;$itemTpl = "    <item><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>";$item_str = "";foreach ($arr_item as $item)$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);$newsTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>%s</ArticleCount><Articles>$item_str</Articles></xml>";$result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));return $result;}private function logger($log_content){}
}
?>

中文分词index.php运行图片

这里写图片描述
这里写图片描述

中文分词index.php整体代码如下:

说明:方倍工作室接口100,目前免费暂无
他们解释原因如下:

  • 接口100免费提供这些年,受到很多用户欢迎,每天访问量非常大,但由于极个别用户使用机器程序抓取数据以及故意使用DDOS恶意攻击,导致服务器不堪重负,维护费用成倍增长。我们决定关停这些接口,有需要的用户,可以联系QQ 1354386063,购买我们的接口源码,或者自行使用第三方收费接口。网页地址http://www.cnblogs.com/txw1958/p/weixin-api100.html

语音功能公众号显示开通了,不知道为啥没有用,检测中…..

<?phpdefine("TOKEN", "weixin");$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {$wechatObj->responseMsg();
}else{$wechatObj->valid();
}class wechatCallbackapiTest
{public function valid(){$echoStr = $_GET["echostr"];if($this->checkSignature()){echo $echoStr;exit;}}private function checkSignature(){$signature = $_GET["signature"];$timestamp = $_GET["timestamp"];$nonce = $_GET["nonce"];$token = TOKEN;$tmpArr = array($token, $timestamp, $nonce);sort($tmpArr);$tmpStr = implode( $tmpArr );$tmpStr = sha1( $tmpStr );if( $tmpStr == $signature ){return true;}else{return false;}}public function responseMsg(){$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];if (!empty($postStr)){$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);$RX_TYPE = trim($postObj->MsgType);switch ($RX_TYPE){case "text":$resultStr = $this->receiveText($postObj);break;case "event":$resultStr = $this->receiveEvent($postObj);break;case "voice":$resultStr = $this->receiveVoice($postObj);break;default:$resultStr = "";break;}echo $resultStr;}else {echo "";exit;}}private function receiveText($object){if (isset($object->Recognition)){$content = strval($object->Recognition);$mediaid = trim($object->MediaID);}else{$content = trim($object->Content);}if (isset($_SERVER['HTTP_APPNAME'])){include("segment.php");$result = sinasegment($content);if (is_array($result)){switch ($result['category']){case "天气"://$url = "http://api100.duapp.com/weather/?appkey=book97&city=".urlencode($result['keyword']);//$output = file_get_contents($url);//$replyContent = json_decode($output, true);//$replyContent = $result['keyword'];$city = $result['keyword'];include("weather2.php");$content = getWeatherInfo($city);$result = $this->transmitNews($object, $content);return $result;break;case "空气"://$url = "http://api100.duapp.com/airquality/?appkey=book97&city=".urlencode($result['keyword']);//$output = file_get_contents($url);//$replyContent = json_decode($output, true);$keyword =  $result['keyword'];include("airquality.php");$content = getAirQualityChina($keyword);if(is_array($content)){$result = $this->transmitNews($object, $content);}else{$result = $this->transmitText($object, $content);}return $result;default:$replyContent = "还不支持这一功能:".$result['category'];break;}}else{$replyContent = "不能理解你的内容:".$content;}}else{$replyContent = "只能运行在SAE环境!";}if (is_array($replyContent)){$resultStr = $this->transmitNews($object, $replyContent);}else{$resultStr = $this->transmitText($object, $replyContent);}return $resultStr;}private function receiveEvent($object){$replyContent = "";switch ($object->Event){case "subscribe":$replyContent = "欢迎关注 德强1012";case "unsubscribe":break;default:break;      }if (is_array($replyContent)){$resultStr = $this->transmitNews($object, $replyContent);}else{$resultStr = $this->transmitText($object, $replyContent);}return $resultStr;}private function receiveVoice($object){$funcFlag = 0;if (isset($object->Recognition) && !empty($object->Recognition)){$content = strval($object->Recognition);include("segment.php");$result = sinasegment($content);if (is_array($result)){switch ($result['category']){case "天气":// $url = "http://apix.sinaapp.com/weather/?appkey=trialuser&city=".urlencode($result['keyword']);//$output = file_get_contents($url);//$replyContent = json_decode($output, true);$city = $result['keyword'];include("weather2.php");$content = getWeatherInfo($city);$result = $this->transmitNews($object, $content);return $result;//$replyContent = $result['keyword'];break;default:$replyContent = "还不支持这一功能:".$result['category'];break;}}else{$replyContent = "不能理解你的内容:".$content;}}else{$replyContent = "未开启语音识别功能";}if (is_array($replyContent)){$resultStr = $this->transmitNews($object, $replyContent);}else{$resultStr = $this->transmitText($object, $replyContent);}return $resultStr;}private function transmitText($object, $content, $flag = 0){$textTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content><FuncFlag>%d</FuncFlag></xml>";$resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content, $flag);return $resultStr;}private function transmitNews($object, $arr_item){if(!is_array($arr_item))return;$itemTpl = "    <item><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>";$item_str = "";foreach ($arr_item as $item)$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);$newsTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>%s</ArticleCount><Articles>$item_str</Articles></xml>";$result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));return $result;}
}
?>

空气质量airquality.php整体代码如下:

<?phpfunction getAirQualityChina($city)
{//http://www.pm25.in/api/querys/aqi_details.json?stations=no&city=%E6%B7%B1%E5%9C%B3&token=5j1znBVAsnSf5xQyNQyq$url = "http://www.pm25.in/api/querys/aqi_details.json?stations=no&city=".urlencode($city)."&token=5j1znBVAsnSf5xQyNQyq";$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);curl_close($ch);$cityAir = json_decode($output, true);if (isset($cityAir['error'])){return $cityAir['error'];}else{$result = "空气质量指数(AQI):".$cityAir[0]['aqi']."\n"."空气质量等级:".$cityAir[0]['quality']."\n"."细颗粒物(PM2.5):".$cityAir[0]['pm2_5']."\n"."可吸入颗粒物(PM10):".$cityAir[0]['pm10']."\n"."一氧化碳(CO):".$cityAir[0]['co']."\n"."二氧化氮(NO2):".$cityAir[0]['no2']."\n"."二氧化硫(SO2):".$cityAir[0]['so2']."\n"."臭氧(O3):".$cityAir[0]['o3']."\n"."更新时间:".preg_replace("/([a-zA-Z])/i", " ", $cityAir[0]['time_point']);$aqiArray = array(); $aqiArray[] = array("Title" =>$cityAir[0]['area']."空气质量", "Description" =>$result, "PicUrl" =>"", "Url" =>"");return $aqiArray;}
}?>

天气查询weather2.php整体代码如下:

<?php//var_dump(getWeatherInfo("桃江"));function getWeatherInfo($cityName)
{if ($cityName == "" || (strstr($cityName, "+"))){return "发送天气加城市,例如'天气深圳'";}//1a3cde429f38434f1811a75e1a90310c$ak = '1a3cde429f38434f1811a75e1a90310c';$sk = '';$url = 'http://api.map.baidu.com/telematics/v3/weather?ak=%s&location=%s&output=%s&sn=%s';$uri = '/telematics/v3/weather';$location = $cityName;$output = 'json';$querystring_arrays = array('ak' => $ak,'location' => $location,'output' => $output);$querystring = http_build_query($querystring_arrays);$sn = md5(urlencode($uri.'?'.$querystring.$sk));$targetUrl = sprintf($url, $ak, urlencode($location), $output, $sn);// var_dump($targetUrl);$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $targetUrl);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$result = curl_exec($ch);curl_close($ch);$result = json_decode($result, true);if ($result["error"] != 0){return $result["status"];}$curHour = (int)date('H',time());$weather = $result["results"][0];$weatherArray[] = array("Title" =>$weather['currentCity']."天气预报", "Description" =>"", "PicUrl" =>"", "Url" =>"");for ($i = 0; $i < count($weather["weather_data"]); $i++) {$weatherArray[] = array("Title"=>$weather["weather_data"][$i]["date"]."\n".$weather["weather_data"][$i]["weather"]." ".$weather["weather_data"][$i]["wind"]." ".$weather["weather_data"][$i]["temperature"],"Description"=>"", "PicUrl"=>(($curHour >= 6) && ($curHour < 18))?$weather["weather_data"][$i]["dayPictureUrl"]:$weather["weather_data"][$i]["nightPictureUrl"], "Url"=>"");}return $weatherArray;
}?>

分词功能函数segment.php整体代码如下:

<?php// $str="深圳天气怎么样";
//$result = sinasegment($str);  
// print_r($result) ;
function sinasegment($str)
{$seg = new SaeSegment();$ret = $seg->segment($str, 1);if ($ret === false){return;}$category = "";$keyword = "";foreach ($ret as $key => $value) {if ($value["word_tag"] == 95){$category = $value["word"];}if ($value["word_tag"] == 102){$keyword = $value["word"];}}if (!empty($category) && !empty($keyword)){return array('category'=>$category, 'keyword'=>$keyword); }else{return;}
}?>

这篇关于微信公众号最佳实践 ( 9.7)智能问答,关键词回复,中文分词的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/289510

相关文章

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

《SpringBoot整合SSE的高级实践(Server-SentEvents)》SSE(Server-SentEvents)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实... 目录1、简述2、Spring Boot 中的SSE实现2.1 添加依赖2.2 实现后端接口2.3 配置超时时

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

Python 中的 with open文件操作的最佳实践

《Python中的withopen文件操作的最佳实践》在Python中,withopen()提供了一个简洁而安全的方式来处理文件操作,它不仅能确保文件在操作完成后自动关闭,还能处理文件操作中的异... 目录什么是 with open()?为什么使用 with open()?使用 with open() 进行

SpringBoot实现微信小程序支付功能

《SpringBoot实现微信小程序支付功能》小程序支付功能已成为众多应用的核心需求之一,本文主要介绍了SpringBoot实现微信小程序支付功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录一、引言二、准备工作(一)微信支付商户平台配置(二)Spring Boot项目搭建(三)配置文件

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio