您好,我们已经来到了人工智能的领域,我们将实现 图灵测试、自然语言处理,这些东西太好玩了,以至于我想先给成品。
人和计算机的区别,仅仅在于“意识”,其实计算机完全可以假装自己有意识、假装自己是智能的。
那该如何评估计算机是否智能呢 ?
图灵测试
大家应该知道计算机之父· ,以及美国计算机协会的最高奖· 。
图灵一生的贡献远不止提出了计算机的数学模型(图灵机),TA的贡献非常大,而且非常广。
比如,图灵花了很多时间思考机器智能的本质,并且为了这个目的研究了形式逻辑学。
在机器智能方面,TA最大的贡献就是提出了一种客观判定计算机是否有智能的标准,即所谓的图灵测试。(图灵测试每年都有比赛)
进行多次测试后,如果机器让平均每个参与者做出超过 30% 的误判,那么这台机器就通过了测试,并被认为具有人类智能。
以下是我测试的结果(绿色语句是我的问题,白色语句是图灵机器人的回答):
以下是图灵测试的代码,您不需要看懂TA,我们将为您
的解释:
import requests, json
# 接入API的信息:id、apikey
id = '377320'
apikey = 'd81c0b99c260440980a140440be200ec'
question = ''
while question != '0':
question = input("请随意提问(输入 0,结束对话): ")
# 创建post的待上传数据
payload = json.dumps({
"reqType":0, # 输入类型:0-文本(默认)、1-图片、2-音频
"perception": {
"inputText": {
"text": question # 输入需要交互的信息
},
},
"userInfo": { # 用户信息
"apiKey": apikey,
"userId": id
}
})
res = requests.post('http://openapi.tuling123.com/openapi/api/v2', data = payload)
# 使用爬虫程序代替浏览器实现 POST 方式的请求
robot = json.loads(res.text)['results'][0]['values']['text']
# json.loads的功能是把 res.text 里面的字符串转换为字典,这样我们才能像提取字典一样的提取 [text] 的数据
# [text] 是一个字典的值,单独取出来赋给了变量 robot 就是字符串类型了
print('图灵测试结果:> ', robot, end='\n\n')
# 图灵测试,Python基础语法
jude = input('请判断当前聊天的是 [人] 还是 [计算机] :> ')
if jude == '人':
print('机器通过测试,具有智能。')
elif jude == '计算机':
print('你,见过这么机智的智能机器人么?')
else:
print('输入错误,请输入 [人] 或 [计算机]')
我们将要爬取的是一家以【语义和对话技术为核心的人工智能】公司研发的聊天机器人,网站是:http://www.turingapi.com/
请新建一个浏览器标签页,跟随操作。首先,进入这个网页。
首先点击【注册/登录】,注册账户,点击【创建机器人】。
点击创建好的机器人,会看到产生了 apikey(相当于身份证)。
apikey的右侧是对话界面,您可以跟TA对话。
:接入图灵机器人的关键就是接入这个聊天功能。
API文档
下一步,打开图灵机器人的帮助文档了解相关内容。
,能实现图灵机器人的通信。
API:https://www.kancloud.cn/turing/www-tuling123-com/718227
为了指定具体的图灵机器人,我们需要上传 id、apikey。
# 接入API需要的用户信息:id、apikey
id = '377320' # 虽然没说要加 id,但如果不加 id 会输出【请求参数缺失】
apikey = 'd81c0b99c260440980a140440be200ec'
API文档里有
说明:
对话聊天,传输的数据是
:
reqType = 0 #或者不写这个参数,因为已经默认了reqType = 0
perception = input('输入对话信息') # 这个参数代表了我方的对话内容
userInfo = 用户信息(也就是 id、 apikey)
写成代码即:
{
"reqType":0, # 输入类型:0-文本(默认)、1-图片、2-音频
"perception": {
"inputText": {
"text": input("请输入:> ") # 输入需要交互的信息
},
},
"userInfo": { # 用户信息
"apiKey": 'd81c0b99c260440980a140440be200ec',
"userId": '377320'
}
}
JSON
。
json 是一种用于网络传输的轻量级数据格式,为了解决不同编程语言在网络中传输数据的不兼容性,考虑到字符串在各种编程语言的通用性,所以开发者研发出 json数据类型,通过 json 实现将 。
API文档有一个带参数请求的模版:
通过上面的【请求示例】,我们发现上传的数据是一个
。
[ json ] 格式大多数编程语言都支持,Python 的是一个叫 【Json】的模块。
通过【模块三问】得到:
- json.dumps( ) 用于将字典形式的数据转化为字符串;
- json.loads( ) 用于将字符串形式的数据转化为字典;
- 显然,dumps(装的是字典),loads(装的是字符串)。
这些参数是字典类型,为了实现跨平台的传输,我们要使用 json.dumps( )用于将字典形式的数据转化为字符串,字符串在【任何平台都/编程语言】都是支持的。
json.dumps({ # 字典转为字符串
"reqType":0, # 输入类型:0-文本(默认)、1-图片、2-音频
"perception": {
"inputText": {
"text": input("请输入:> ") # 输入需要交互的信息
},
},
"userInfo": { # 用户信息
"apiKey": 'd81c0b99c260440980a140440be200ec',
"userId": '377320'
}
})
POST请求
带参数请求的所有参数都准备完毕。
明确接口地址即浏览器发起请求的 ,其次 为 POST请求。
GET 我们知道了,POST 又是什么呢 ?
上网冲浪从本质上来说,只有俩种动作:
- 一种是从服务器那儿拿数据,称作 GET;
- 一种是把我们这里的信息交给服务器去处理,称作 POST。
我们在使用浏览器上网时,并不总是只下载内容,还有许多上传的动作:翻评论时跳转的页码页,搜索或翻译时输入的文字,玩网页小游戏的点击互动……
表面看,是网页会根据我们的操作,实时地返回结果。
实际上,是我们通过点击鼠标的操作,向服务器发起一个带参数的请求,服务器处理这个请求,并返回了结果,所以这些都是 POST 请求。
爬虫实现 POST 请求:
requests.post( ) 我没学过怎么办 ?
- requests.post( ) 能向服务器传输数据;
- 需要输入一个网址、一个待上传的数据;
- .text 获取文本 和 .content 获取音乐类数据;
待上传的数据就是 Json:
import json
id = '377320'
apikey = 'd81c0b99c260440980a140440be200ec'
question = input("请随意提问:> ")
# 创建post的待上传数据,json.dumps()用于将字典形式的数据转化为字符串
payload = json.dumps({
"reqType": 0, # 输入类型:0-文本(默认)、1-图片、2-音频
"perception": {
"inputText": {
"text": 'question' # 输入需要交互的信息, 即 input('输入对话信息')
},
},
"userInfo": { # 用户信息
"apiKey": 'apikey',
"userId": 'id'
}
})
print(payload)
print(type(payload))
输出:
现在我们就能读懂 70% 的代码了。
import requests, json
# 接入API的信息:id、apikey
id = '377320'
apikey = 'd81c0b99c260440980a140440be200ec'
question = ''
while question != '0':
question = input("请随意提问(输入 0,结束对话): ")
# 创建post的待上传数据
payload = json.dumps({
"reqType":0, # 输入类型:0-文本(默认)、1-图片、2-音频
"perception": {
"inputText": {
"text": question # 输入需要交互的信息
},
},
"userInfo": { # 用户信息
"apiKey": apikey,
"userId": id
}
})
res = requests.post('http://openapi.tuling123.com/openapi/api/v2', data = payload)
# 使用爬虫程序代替浏览器实现 POST 方式的请求
提取JSON数据
我们与图灵机器人的交互过程 :先上传的对话信息,服务器解析数据后,会返回给我们的结果。
所以目标数据不会写进网页源代码,一定是在 Json 传输。
鼠标右击【检查】。
鼠标右键打开检查工具(Windows快捷方式是ctrl+shift+c),选择【Network】-【XHR】。
打开后,发现空空如也。
这是因为 【Network】 记录的是实时网络请求。现在网页都已经加载完了,当然不会有东西。
刷新,浏览器会重新访问网络,这样就会有记录。
【Network】能够记录浏览器的所有请求。
- ALL(查看全部)/XHR(仅查看XHR)/Doc(Document,第 1 个请求一般在这里);
- Img(仅查看图片)/Media(仅查看媒体文件)/Other(其他);
- JS和CSS,则是前端代码,负责发起请求和页面实现;
- Font是文字的字体。
我们平时在使用浏览器上网的时候,经常会有这样的情况:网址没变,但是网页里面的一部分内容却变了。
如购物网站,下滑自动加载出更多商品。在线翻译网站,输入中文翻译英文。这说明,即便我们没有进行翻页/跳转/刷新的操作,浏览器也在和服务器实时地传输一些数据。这个动作,就通过 【XHR(XHR and Fetch)】来实现。
其实图灵机器人的回答,就在 【XHR】里,我们点击的XHR,这样屏幕上的请求就都是【XHR】类型。
我们分析一下,对话过程看看服务器是如何传输数据的。
现在的界面,空空如也。
输入对话:你好呀~
服务器解析后,右边就多了一个文件,我们需要的数据就在里面。
打开后可以看见几个固定标签如 Headers、Preview、Response、Cookies、Timing。
- Headers:标头(介绍信息)
- Preview:预览
- Response:原始信息
- Timing:时间
点击Preview,可以查看到浏览器从服务器那里得到的请求数据(JSON数据类型),图灵机器人的回复存储在嵌套的字典数据里面。
JSON传输的数据在【XHR】文件里,TA是一个字典。
比如,图灵机器人的回答就在图中,TA的键是【text】。
- 这个【XHR】是一个字典,键【data】对应的值也是一个字典;在该字典里,
- 键【results】对应的值是一个列表,在该列表里,
- 有 1 个元素,也是字典;在该字典里,
- 键【text】的值,对应的是图灵机器人的回答。
一层一层的展开:results -> 0 -> values -> text,而后就能看到 “别兴奋别兴奋,很高兴认识你!”
按照路径提取数据,还需要一个函数:json.loads( )。
json.loads( ):把字符串转为字典。
robot = json.loads(res.text)['results'][0]['values']['text']
# json.loads的功能是把 res.text 里面的字符串转换为字典,这样我们才能一层一层的取字典,获得 [text] 的数据
# [text] 是一个字典的值,单独取出来赋给了变量 robot 就是字符串类型了
print(robot)
# 输出提取的结果
好的,现在应该是能读懂整个图灵机器人的代码了。(要是对 Python 语法不熟悉,那我也没办法~)
import requests, json
# 接入API的信息:id、apikey
id = '377320'
apikey = 'd81c0b99c260440980a140440be200ec'
question = ''
while question != '0':
question = input("请随意提问(输入 0,结束对话): ")
# 创建post的待上传数据
payload = json.dumps({
"reqType":0, # 输入类型:0-文本(默认)、1-图片、2-音频
"perception": {
"inputText": {
"text": question # 输入需要交互的信息
},
},
"userInfo": { # 用户信息
"apiKey": apikey,
"userId": id
}
})
res = requests.post('http://openapi.tuling123.com/openapi/api/v2', data = payload)
# 使用爬虫程序代替浏览器实现 POST 方式的请求
robot = json.loads(res.text)['results'][0]['values']['text']
# json.loads的功能是把 res.text 里面的字符串转换为字典,这样我们才能像提取字典一样的提取 [text] 的数据
# [text] 是一个字典的值,单独取出来赋给了变量 robot 就是字符串类型了
print('图灵测试结果:> ', robot, end='\n\n')
# 图灵判断
jude = input('请判断当前聊天的是 [人] 还是 [计算机] :> ')
if jude == '人':
print('机器通过测试,具有智能。')
elif jude == '计算机':
print('你,见过这么机智的智能机器人么?')
else:
print('输入错误,请输入 [人] 或 [计算机]')
图灵测试的结语
像图灵机器人的存在,其实并不说明机器人水平高,而恰恰说明了一般人的水平低!
这是因为我们一般人,面对一个陌生人的时候,我们的聊天内容其实大都是程序化的。
一般都是:你好、你多大了、你是大学生吗 … 全是循规蹈矩的寒暄。
机器人想要模仿这种说话非常容易(假装有意识、假装是智能的)。
有人专门研究了在线交友网站上的聊天,发现就是因为这种程序化的对话,让俩个人的关系很难升温一步。
并不是聊天机器人很像人,而是人的聊天太像机器人。
所以研究者就专门开发了一套新的聊天系统,让俩个人在对话的开始阶段就能迅速进入比较深的话题 —— 比如说系统会要求您在以下问题中选一句发给对方:
- 你有过几个浪漫关系的伴侣?
- 你上次分手是什么时候?
- 你伤过别人的心吗?
实验表明这种问题一出来,俩个人的对话马上就能更有意思。
问题在于,真实生活中没人愿意这么说话。
事实上我们的说话风格正在加速向机器人的方向靠拢。
过去您听说了别人的近况,看到她旅游时的照片,还要评论几句 —— 现在您只需点赞。
也许,人们连情绪都会标准化;这种标准化,完全沉溺在数据之中。
【扩展阅读】
Get 和 Post 的区别:http://www.w3school.com.cn/tags/html_ref_httpmethods.asp
requests 官方文档:http://cn.python-requests.org/zh_CN/latest/
【复习】
黑客技巧:万能密码
当网页需要登陆账号密码时,采用的请求方式通常是 POST 请求方式。
对于 POST 请求方式,黑客为了判断表单(账号框和密码框)是否存在注入点,会在表单中输入一个万能密码。
- 万能密码:’ or -1=-1#
这里的 sql 语句是这样的:
where username=‘zkz’ and password=’’ or -1=-1# limit 0,1。
第一个引号是为了闭合密码框的引号,or -1=-1 为了让 where 语句成立,#可以把后面的内容都注释掉。
如果网站存在 POST 注入点,就能登录成功(账号+万能密码)。