python第三方聊天机器人_用 Python 来做一个聊天机器人吧!(特别篇)

本文介绍了如何使用Airtest(Poco)框架在安卓模拟器上自动处理QQ消息,包括消息的读取和发送。通过Python编程,配合Poco的UI控件搜索功能,实现在聊天室中实现消息筛选和发送,适合自动化测试或日常任务自动化需求。
摘要由CSDN通过智能技术生成

何去何从?

原计划第三篇要写机器学习的内容,然而文章还没写完,酷Q没了。

可是,真的没有办法了吗?

我们相信冬天总会过去,不过,在春天到来之前,生一丛篝火取暖,也算是聊胜于无吧。

这篇文章,我将介绍如何使用 Airtest(Poco) 框架进行简单的 QQ 消息自动收发处理。

关于 Airtest

Airtest是一款网易出品的自动化测试套件,包括 Airtest(图像识别)、Poco(UI控件搜索)和 Airtest IDE。Airtest 提供了一系列自动操作应用程序的接口,我们利用这些接口,就可以实现 QQ 消息的自动收发处理。

Airtest 也是基于 Python 开发的,因此可以和之前两篇文章中介绍的 chatterbot (以及没来得及写的 pytorch)很好地协作。

Airtest 可以在官网下载,其中 Airtest IDE 需要登录账号才能使用。(可以使用网易账号或者 Github 账号登陆。)如果需要不依赖于 Airtest IDE,直接从命令行启动脚本,还需在本地的 Python 环境中安装 Airtest 库:

pip install airtest pocoui

一些构想

自 QQ 的第三方协议关停以来,我一直在寻求替代方案。从 Github 上一个名叫 FoolQQ 的项目得到启发,我想出了自动化操作的方法。

首先在安卓模拟器上运行QQ并登陆账号(为什么不用PC版?因为 Airtest 对安卓的支持相对更成熟),然后使用 Airtest 这样的框架来读取其中的内容,或者发送消息。目前这种方法可以实现单个聊天中的消息收发。

在模拟器的选择上,我使用的是逍遥模拟器,它对 QQ 和 Airtest 的兼容性都不错。为了节省空间,我选择了 QQ 极速版(原轻聊版),以下内容均以此版本为依据。

使用 Poco

Poco 是 Airtest 中的 UI 控件搜索框架,基于 uiautomatior2,支持对 Android 原生应用以及一些游戏引擎中 UI 元素层级的解析。有一个好消息,在 QQ 的界面中,所有的控件都是采用了继承修改 Android 原生控件的模式,这使得我们能够直接利用 Poco 读取消息内容,避免了复杂的 OCR 实现。

在阅读这一章节之前,可以先去看看 Airtest 的文档,了解一下 Airtest 的基础知识以及 IDE 的使用,并掌握在 IDE 中连接安卓模拟器的方法。

连接模拟器之后,运行 QQ,然后在 IDE 的「Poco 辅助穿」的下拉列表中选择「Android」,可以看到这样的 UI 渲染树:

双击其中的元素,就可以在脚本编辑器中生成选择这个元素的代码。

在 QQ 轻聊版的聊天界面,通过这种方式,我们分析出了几个关键的 UI 控件:poco("com.tencent.qqlite:id/listView1") 这个控件是当前显示的聊天内容,它有若干个包名为com.tencent.qqlite:id/base_chat_item_layout的子节点,每个子结点的包名为com.tencent.qqlite:id/chat_item_content_layout 的子节点的text属性就是消息内容。

poco("com.tencent.qqlite:id/input")底部输入框。

从这些出发,我们得到了查看当前显示的消息的代码:

def get_message_list():

def get_message_list_iter():

try:

msg_list = poco("com.tencent.qqlite:id/listView1")

for msg_container in msg_list.child("com.tencent.qqlite:id/base_chat_item_layout"):

msg = msg_container.child("com.tencent.qqlite:id/chat_item_content_layout")

if msg.get_position()[0] < 0.5: # 排除自己发送的消息

txt = msg.get_text()

if txt:

yield txt.strip()

finally:

pass

return [msg for msg in get_message_list_iter()]

以及发送消息的代码:

def send_message(msg_text):

try:

input_box = poco("com.tencent.qqlite:id/input")

input_box.click()

input_box.set_text(msg_text)

keyevent("ENTER") # 请在 QQ 的「设置-通用」中选中「回车键发送消息」

return True

except:

return False

但是 Poco 只能获取控件的基本信息,这就导致了我们无法得到消息的发送时间。为了能获取“新消息”,我们采用类似于轮询的机制,每隔一段时间获取一下消息列表,对比最新消息的内容有无变化,如果有变化,就认为之后的消息都是“新消息”。这种办法不能识别有人复读的情况,不过问题不大。

这个过程可以抽象为一个类:

class MessageListener(object):

def __init__(self):

message_list = get_message_list()

if message_list:

self.latest_message = message_list[-1]

else:

self.latest_message = None

def check_latest_message(self):

message_list = get_message_list()

if message_list:

if self.latest_message is None:

self.latest_message = message_list[-1]

return []

def check_latest_message_iter():

for msg in reversed(message_list):

msg = msg

if msg == self.latest_message:

break

yield msg

result = reversed(list(check_latest_message_iter()))

self.latest_message = message_list[-1]

return result

else:

return []

这三段代码是实现消息自动收发的基础。

综合一下

这里给出完整的代码(core.py):

# -*- encoding=utf8 -*-

# core.py

__author__ = "忘忧北萱草"

from poco.drivers.android.uiautomation import AndroidUiautomationPoco

from airtest.core.api import *

import logging

logger = logging.getLogger("airtest")

logger.setLevel(logging.ERROR) # 屏蔽多余的日志输出

# 以下是连接安卓模拟器用的代码。如果你是在 Airtest IDE 中运行这些代码,可以删去下一行以及 auto_setup 中的 devices 参数

# 21503 端口是逍遥模拟器的默认端口,如果你使用的不是逍遥,请按照 Airtest 的文档说明更改此处

simulator = "Android://127.0.0.1:5037/127.0.0.1:21503?cap_method=JAVACAP^&^&ori_method=ADBORI"

auto_setup(__file__, devices=[simulator])

poco = AndroidUiautomationPoco(

use_airtest_input=True, screenshot_each_action=False)

# 目前还不支持自动进入某个聊天,所以请手动启动 QQ 并打开聊天界面

# start_app("com.tencent.qqlite")

# 获取当前消息

def get_message_list():

def get_message_list_iter():

try:

msg_list = poco("com.tencent.qqlite:id/listView1")

for msg_container in msg_list.child("com.tencent.qqlite:id/base_chat_item_layout"):

msg = msg_container.child(

"com.tencent.qqlite:id/chat_item_content_layout")

if msg.get_position()[0] < 0.5:

txt = msg.get_text()

if txt:

yield txt.strip()

finally:

pass

return [msg for msg in get_message_list_iter()]

# 发送消息

def send_message(msg_text):

try:

input_box = poco("com.tencent.qqlite:id/input")

input_box.click()

input_box.set_text(msg_text)

keyevent("ENTER")

return True

except:

return False

# 消息轮询

class MessageListener(object):

def __init__(self):

message_list = get_message_list()

if message_list:

self.latest_message = message_list[-1]

else:

self.latest_message = None

def check_latest_message(self):

message_list = get_message_list()

if message_list:

if self.latest_message is None:

self.latest_message = message_list[-1]

return []

def check_latest_message_iter():

for msg in reversed(message_list):

msg = msg

if msg == self.latest_message:

break

yield msg

result = reversed(list(check_latest_message_iter()))

self.latest_message = message_list[-1]

return result

else:

return []

使用方法参看以下的 demo:

import random

import core

if __name__ == '__main__':

messageListener = core.MessageListener()

print('初始化完成。')

while True:

messages = messageListener.check_latest_message()

for msg in messages:

print('>>> '+msg)

if msg == '报告状态':

core.send_message('执行自检……连接不稳定……')

core.sleep(1)

本文所提到的技术已在 Github 上开源:https://github.com/Wybxc/YiriAir​github.com

结语

这篇文章写的有些仓促,不像之前两篇那么详细,因为我想尽快把我的经验分享给大家。

以上。

(封面PID:75286867)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值