才权的博客


  • 首页

  • 归档

  • 标签

  • 关于

Eddy的AI小助手Requests Http模块(14)

发表于 2017-07-12

Python的原生Http请求库是urllib,但urlib在实际开发中,使用并不方便。Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作。在AI小助手中的Http请求均是基于Requests的。

模块工程位置,

Requests在工程中的引用位置

Requests库项目地址

http://www.python-requests.org/en/master/

项目地址

Java代码:http://github.com/CaiquanLiu/MyWeChatService.git
Python代码:https://github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-Tornado Web模块(13)

发表于 2017-07-12

Python后台采用Tornado作为Web Server。Tornado的部署和使用非常简单。

Tornado安装

pip install tornado

Hello World示例

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Tornado官方网址:

http://www.tornadoweb.org/en/stable/

微信信息处理服务入口

MyTuringService接收并处理来自MyWeChatService的http请求。

微信信息处理服务入口

其中,

  • wechat_server.py:web Server入口;
  • http_client.py:模拟微信请求(测试使用);

项目地址

Java代码:http://github.com/CaiquanLiu/MyWeChatService.git
Python代码:https://github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-添加基于Jenkins的自动化构建系统(12)

发表于 2017-07-07

引入Jenkins构建的缘由

先梳理下我们先前的代码上线流程:

  • 本地代码编写
  • 本地Web服务器验证
  • 代码上传GitHub
  • 通过Eclipse将Java Web工程编译、打包成war文件
  • 通过网络工具如WinSCP将war包上传线上Web服务器
  • 线上Web服务器运行更新后的war,支持新的功能上线成功
    上面的过程中,4、5、6步骤,其实可以通过可视化的形式,一键完成,如下图所示:

微信小助手的Jenkins构建平台

构建平台地址:http://120.25.220.14:8082

只需点击“立即构建”按钮,就能完成新功能的上线,是不是很方便?

Jenkins构建流程

  • 从代码库拉去代码(本例中是从GitHub上拉去代码)
  • 云端编译打包
  • 云端发布

具体实现

本例中的Jenkins服务器是同微信小助手的Web Service在同一物理机上的。
为了支持Jenkins编译,源于的小助手工程添加了build.xml和build.sh两个文件:
添加build.xml和build.sh文件
Jenkins的构建控制:

  • 创建新的Jenkins Job时,会绑定对于项目的git库地址
  • Jenkins从GitHub将代码拉取到本地;
  • 执行编译脚本build.sh
  • build.sh脚本调用Ant命令进行编译和上线发布(build.xml是Ant的控制脚本)

ps:Ant是一种用于构建控制的工具,类似同于C/C++中常见的Make CMake,Java中常见的Maven和Gradle;

项目地址

Java代码:http://github.com/CaiquanLiu/MyWeChatService.git

Python代码:https://github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-数据处理模块实现(11)

发表于 2017-07-07

Python数据处理模块结构总览

Python版本:2.7.13

Http Server:Tornado

Http请求库:Requests

IDE:PyDev+Eclipse

工程目录,

工程目录

  • turing:图灵机器人的请求封装模块(www.tuling123.com/);
  • utils:通用工具模块,当前只包含基于requests的http请求封装;
  • common_params:通用的常量定义模块;
  • http_request:http请求测试模块
  • test:本地功能测试模块
  • tornado_server:基于Tornado的web服务模块(部署在服务器中)

工程使用

本地功能测试

使用test进行本地功能的测试,比如测试本地的图灵请求功能,

图灵机器人接口模块测试代码

测试结果

Tornado web服务部署

在服务器端启动tornado_server模块即可,

#python tornado_server.py

Http请求测试

在部署好tornado_server web服务后,使用http_request模块完成http请求测试。比如客户端请求服务端的图灵能力(服务端调用图灵接口),

http请求测试代码

测试结果

其中,服务端与客户端之间基于Json进行通信。

项目代码

Java代码:github.com/CaiquanLiu/MyWeChatService.git

Python代码:github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-后台处理模块接入(10)

发表于 2017-07-07

Python后台处理模块接入的缘由

Python

前面的后台搭建都是基于Java EE的,但后面随着对机器学习的深入,慢慢发现大多数机器学习的算法实现都是基于Python和R语言的。R语言主要集中在对数据的预处理、分析和展示,而Python不但囊括了R语言的功能,还延伸到了网络请求、Web服务、数据抓取等方方面面。Python不但在语法上入门简单、在开发环境的搭建上相对容易,开发IDE也很完善易用。在机器学习领域有很多现成的算法库,开源工具包非常完备。Python一旦入门,绝对会对它爱不释手的 :)

Python学习的个人经验

既然是个人经验,就要先交代下自己在学习python之前的编程经历。从大学一年级接触C语言,并在大学二年级在电子设计竞赛中投入真正的开发使用,直到进入互联网公司之前,都是在使用C语言做底层驱动和中间件开发,使用C++做业务逻辑开发。进入互联网之后开始接触Java,并进行Android中间件和应用开发。在业余时间自学了Java EE的开发流程并了解了Web前端开发的基础知识。

我的Python学习比较简略:

快速入门

在网上看一篇关于Python的入门帖子,比如www.runoob.com/python/python-basic-syntax.html,在这个过程中了解语言特性和基本语法、搭建基本的运行环境,这个过程1~2个小时足矣。

全局把握

对Python有了基本的了解和认识后找一本大而全的教科书,比如《Python基础教程》(我找了本电子版),这是一本很厚的书。然后查看目录,并逐页“扫读”(所谓“扫读”就是非常快速的粗略阅读和跳读,在阅读的过程中并不需要逐行逐句,而是要粗枝大叶)。对于“魔法方法、属性和迭代器”这样的章节可以仔细研读,对于“条件、循环和其他语句”这样的章节可以一扫而过、对于“图形用户界面”这样的章节则可以直接跳过不看。整个过程的一个核心思想是:

  1. 对比阅读,发掘Python相对于自己以往掌握的语言有哪些相同点和不同点;

  2. 系统把握,明了整个Python语言的系统体系和知识组成;

  3. 确定目标,扫读的目标是在后续如果遇到相应的Python问题,能够快速的定位到具体的知识点,并查询答案(这本大厚书可以在以后作为字典类的工具书使用)

第二个步骤需要半天到一天的时间。

工程实践

在Python终端敲简单的命令显然无法满足我们的工程需要,一个完整的工程开发需要便捷的开发工具和清晰的模块关系。这里我使用DevPy+Eclipse搭建IED开发环境,工程中引入包、模块、类等Python特性来明晰项目中的模块关系。在开发中遇到问题则通过查询《Python基础教程》或在网上搜寻解决方法。

Python后台处理模块的功能和接入方式

Python的后台处理模块主要用来做机器学习相关的处理工作。Python模块引入了Tornado Web引擎,对外以REST API的形式提供服务。所以简单的说Python的后台处理模块也是像基于Java EE一样的Http Web服务。

后记(自己的语言学习感悟)

汇编语言

对于汇编语言相信绝大多数同学除了在《微机原理》的实验课上使用过之外,应该在真实工作中很少有接触,即便对于很多嵌入式开发的同学在工作中也很难接触的到。我在工作中唯一的实践经历是修改中断向量表。是在一个没有MMU的MCU上保证运行的ucOS系统能够有独立的Bios、Bootloader、App三个独立的运行空间。当时的解决方案是使用两级中断向量表:硬件触发中断后会自动跳转到第一级的中断向量表,而第一级的中断向量表直接指向第二级中断向量表。第二级中断向量表会通过检查硬件管脚的状态转跳到Bios、Bootloader、App不同空间的处理代码段。汇编语言的学习重点不是语言本身,而是机器运行的机制。

C语言

相比于汇编C语言确实算是高级语言了。对于互联网的同学来说C语言的语法很简单,C语言的指针又很眩晕,在功能开发上,很简单的事情要写上一大堆代码。其实业务开发并不是C语言的优势所在,C语言更多是为了取代汇编,同样C语言的学习重点也不在于语言本身,更在于对系统运行机制的理解,所以,C语言更多的应用场景是驱动开发和协议解析。

C++

相比于C语言,C++对业务逻辑的处理能力大大增强,同时,设计模式在C++中的应用也变得得心应手。但C++只能算的上C语言的升级版,作为程序员,并不能完全脱离系统原理的限制,将全部的注意力放在业务逻辑的实现上。但劣势同样也是优势,正是C++同系统的相关性才使得C++在嵌入式设备和实时性较高的核心中间件领域留有一席之地。

Java

相对于C++,Java实现了完全的面向对象。从解放劳动力的角度讲,Java实现了一次飞跃。开发人员再也不用被底层的系统机制所牵绊,将自己的更多精力放在业务逻辑本身,同时,Java的各种工具支持包也很完备。这也很好的解释了,为什么嵌入式领域一个项目的开发周期往往是2~3年,开发成员往往是几十甚至是几百人。而互联网产品很多都是几个人或一个人,一周或一个月的作品。但不可否认,Java自身的运行机制,导致它对系统资源的高要求和运行时的低效率,这也是Java在特有领域不能完全替代C++的原因。

Python

在接触Python之前,我一直认为Java是用起来最爽的语言(简单的运行和开发环境搭建、功能强大的IDE工具、完备的工具包支持),但接触到Python之后才发现我的结论下的太早了。相比于Java,Python除了是脚本语言、动态语言这样的基本属性之外,Python的一个很大的特点是简洁。Python能够使用更少的代码,更少的依赖完成你想要的工作。

当然语言和算法一样,没有一个算法能使用所有的场景,也没有一种语言能驾驭所有的领域。

Eddy的AI小助手-自定义语义解析和内容抓取(9)

发表于 2017-07-07

需求提出

上一篇文章中我们接入了图灵机器人,通过图灵机器人接口,我们可以实现查天气、看股票、听故事这样的需求。但如果我现在需要查看下我的简书上有哪些文章该如何处理呢?显然通过图灵机器人接口是不能实现的,这里就需要我们自己来完成语义的解析,同时,通过网络爬虫来爬取我在简书上的文章列表。下面我们以“我们简书上有哪些文章?”为例,来说明AI小助手中,自定义语义解析和内容抓取是如何实现的。

语义解析

在AI小助手中对语义的解析分为两个层次:

1 理解意图

意图就是要干什么,也是后台处理的能力范围。对于图灵机器人,它的能力包括“笑话大全”、“故事大全”、“成语接龙”等等:

图灵机器的能力

在接收到用户请求后,图灵机器人会首先分析该请求和自己的那一种能力相对应,如果超过自己的能力范围,图灵机器人便无法进行处理。如果询问图灵机器人“我的简书上有哪些文章?”,用户的意图不在图灵的能力范围之内,它是无法做出正确回复的。

2 确定意图参数

在获取意图之后,就需要确定该意图对应的具体参数。比如“今天天气怎么样?”,图灵机器人能够获取该请求的意图是“天气查询”,但它不知道查询什么地方的天气,所以,也是无法给出正确的答复的。所以正确的询问方式应该是“今天深圳天气怎么样?”图灵机器人在识别到“天气查询”的意图后,还会提取“今天”和“深圳”这样的关键参数,从而返回正确的回复。

3 AI小助手的语义解析

AI小助手采用关键字匹配的方式来分层获取意图和意图对应的参数。对于“我的简书上有哪些文章?”,AI小助手对先匹配关键字“简书”获取意图,然后通过关键字“文章”来获取“简书”意图下的关键参数。

关键字的匹配使用了Java的正则表达式。其中,“简书”意图的匹配规则,

private final String REG_EX_JIANSHU = "简书|jianshu";

“文章”参数的匹配规则,

private final String REG_EX_ARTICLE = "文章|article";

意图和对应参数的提取都是基于字符串查找的,

关键字匹配代码

内容爬取

在正确获取到请求的意图和对应参数后,需要给出正确的答复。对于“我的简书上有哪些文章?”这样的请求,我们可以通过网络爬虫来爬取自己需要的信息。在AI小助手中,采用了HtmlParser(htmlparser.sourceforge.net/)对个人的简书文章进行分析,从而爬取需要的信息。

自定义语义解析与图灵机器人配合使用

自定义语义解析可以同图灵机器人接口配合使用。首先进行自定义的语义解析,如果解析失败再通过图灵机器人接口进行解析。这样既可以满足像“我的简书上有哪些文章?”这样自定义能力,又可以完成像“今天深圳天气怎么样?”这样的通用能力。

AI小助手自定义语义解析和内容抓取效果

自定义意图解析

项目代码

Java代码:github.com/CaiquanLiu/MyWeChatService.git

Python代码:github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-图灵机器人接入(8)

发表于 2017-07-07

前期准备

通过前面的步骤,我们的后台服务器已经可以接收来自微信公众后的消息,并能够将处理的结果返回给微信公众号客户端。如果我们的后台服务器程序能够解析用户的请求意图,并将意图的处理结果返回给客户端,那么我们的AI小助手就具备了真正的“智慧”。

图灵机器人接口

对用户意图的理解,AI小助手使用了图灵机器人请求接口。图灵机器人的官方地址:www.tuling123.com/

图灵机器人有多种接入方式,

图灵机器人接入方式

AI小助手采用API的形式接入图灵机器人。API的请求是基于Http的,支持Get和Post请求,请求和结果返回通过Json进行序列化。天气状况的请求和应答如下图所示:

天气状况查询接口

AI小助手接入演示

使用AI小助手查询天气

项目代码

Java代码:github.com/CaiquanLiu/MyWeChatService.git
Python代码:github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-添加log4j日志工具(7)

发表于 2017-07-07

我们在调试的过程中可以在本地搭建Tomcat服务器,并使之与Eclipse环境相关联。同时,将Eclipse中开发的程序直接部署到本地的Tomcat中运行,从控制台查看打印信息(使用System.out.println()即可)。但在实际的线上环境,是无法实时的查看控制台的打印信息的,我们需要将运行中打印的Log存放到文件中,然后查看文件中的Log信息。对于线上环境的Log打印,AI小助手采用了log4j组件。

log4j组件使用的主要步骤

1 添加jar包

从log4j的官网上下载最新的jar包,并存放在工程的lib目录下,

添加依赖jar包

2 添加log4j配置文件

在src同级创建并设置log4j.properties,

添加log4j配置文件

3 指定log文件的保存路径

设置log保存目录

4 在代码中添加log打印语句

项目代码

Java代码:github.com/CaiquanLiu/MyWeChatService.git

Python代码:github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-微信消息收发(6)

发表于 2017-07-07

微信消息收发规范

微信使用POST请求形式来收发消息,消息以XML形式进行封装,

微信数据收发

微信消息类型

  • 消息类型包括:
  • 文本消息
  • 图片消息
  • 语音消息
  • 视频消息
  • 小视频消息
  • 地理位置消息
  • 链接消息

微信消息的解析实现

微信消息的解析直接使用了黄路飞的代码(www.cnblogs.com/huanglufei/p/5592072.html)

其中,XML的解析使用了XStream组件。

项目地址

Java代码:github.com/CaiquanLiu/MyWeChatService.git

Python代码:github.com/CaiquanLiu/MyTuringService

Eddy的AI小助手-在welcom-file中设置优先响应的Servlet(5)

发表于 2017-07-07

WebApp对Http的默认响应设置

在没有指定具体的响应html页面、jsp页面或Servlet时,Tomcat将Http请求转发给对于的WebApp后,最终由WebApp中的哪一个.html页面、.jsp页面或Servlet来响应,是由web.xml中标签内容决定的(jsp页面等同于Servlet对象)。

针对微信请求的web.xml修改

具体修改如下:

welcome-file-list标签

servlet、servlet-mapping标签

其中,MyWechatMain为Servlet类。

项目地址

Java代码:github.com/CaiquanLiu/MyWeChatService.git

Python代码:github.com/CaiquanLiu/MyTuringService

1…5678
Liu Caiquan

Liu Caiquan

71 日志
11 标签
© 2019 Liu Caiquan
由 Hexo 强力驱动
主题 - NexT.Mist
本站总访问量次