使用Python RPA构建与桌面系统交互的机器人

你可能已经了解了一些工具和框架,可以帮助你构建与Web系统交互的自动化。但是,当涉及到桌面系统时,你该怎么做呢?我来向你展示如何使用BotCity的开源框架,在Python RPA中构建自动化,它具有多种功能。

准备开发环境

  • 在BotCity平台上创建您的免费账户;

  • 按照预先要求和BotCity Studio SDK安装指南的步骤跟踪安装过程;

  • 安装Sicalc(如果您想要使用相同的示例程序来跟随本教程)。

  • 适用于离线操作的Sicalc桌面程序不会生成有效的发票;

  • Sicalc适用于Windows操作系统,但整个流程和框架的使用也可以应用于Linux和MacOS发行版;

  • 第一次打开Sicalc时,将要求输入一个城市代码。在我们的例子中,我们将输入7107代表圣保罗,但也可以是其他城市代码。

开始开发我们的机器人的第一步

从Botity模板创建项目

在您的计算机终端中,在您想要创建项目的文件夹中,执行以下命令来安装cookiecutter包(因为提供的模板是基于它创建的)。

要安装cookiecutter包,请执行以下命令:

python -m pip install --upgrade cookiecutter

为了使用该模板创建项目,我们将调用cookiecutter,并将BotCity模板的存储库URL作为参数提供:

python -m cookiecutter https://github.com/botcity-dev/bot-python-template/archive/v2.zip

在执行此命令期间,您需要提供两个信息:

  • project_type:指的是您要创建的项目类型。模板将提供一些选项,但在这种情况下,我们将选择1,因为我们要构建一个桌面机器人;

  • bot_id:指的是您要为项目设置的标识。在这个例子中,我们将其命名为bot-sicalc。

完成上述过程后,将会出现一个名为bot-sicalc的新文件夹。您可以阅读文档中的指南,了解一些关于结构和功能的更多信息。

安装项目的依赖项

通常,开发项目可能有一些依赖项,如使用的框架、重要的软件包等。我们的项目也有依赖项,您可以在requirements.txt文件中找到它们。您会注意到至少有这两个依赖项:

botcity-framework-core 是一个用于开发自动化的框架。
botcity-maestro-sdk 是用于自动化编排的 BotCity Maestro 的 API。

在运行您的项目之前,很重要的一步是安装依赖项。为此,请执行以下命令:

pip install --upgrade -r requirements.txt

第一次执行我们的机器人

如果您打开bot.py文件,您会发现已经有一些预先编写的代码和一些注释,其中包含了有关如何进行下一步的重要指导。

了解代码在做什么

请找出以下带有以下命令的行。它们在导入我们在requirements.txt文件中提到的库,以便您可以在代码中使用它们。

from botcity.core import DesktopBot
from botcity.maestro import *

在下面的行中,我们正在为机器人创建一个使用Desktop框架的对象,并要求它在BotCity网站上打开一个浏览器。

bot = DesktopBot()
bot.browse("http://www.botcity.dev")

运行机器人

要看机器人执行,请使用您使用的IDE或以下命令行:

python bot.py

成功了吗?您的计算机上的浏览器是否打开了BotCity网站?以下是预期执行后的结果示例:

一个有趣的建议是你测试一下发生的事情是否符合预期。尝试逐步进行测试,以便你能够理解正在发生的事情。这也会帮助你更好地理解并处理任何可能出现的错误。

一个有趣的建议是你测试一下发生的事情是否符合预期。尝试逐步进行测试,以便你能够理解正在发生的事情。这也会帮助你更好地理解并处理任何可能出现的错误。

如果第一次尝试没有成功,不要担心。

当你第一次开发或学习一些全新的东西时,经历一些错误是很正常的。我邀请你阅读这篇文章,了解一些可能发生的错误,并鼓励你分享你遇到的错误以及如何解决它们。

如果你在开发中遇到其他困难,请随时进入我们的论坛或 Slack 社区寻求帮助和解答你的疑问。

开发桌面机器人

在这个开发过程中,我们将使用 BotCity Studio,并借助计算机视觉来帮助我们对系统屏幕上的元素进行映射,以便我们的机器人能够与其互动。

在 BotCity Studio 中加载 BotSicalc 项目

保持你的集成开发环境(IDE)打开,并同时打开 BotCity Studio。在顶部菜单中,选择“File”,然后选择“Load Project”。

在 BotCity Studio 中加载 BotSicalc 项目

打开一个新的窗口,在该窗口中,您需要点击“浏览”并找到您的项目文件夹的位置。

打开一个新的窗口,在该窗口中,您需要点击“浏览”并找到您的项目文件夹的位置。

接下来,找到扩展名为.botproj的文件。选择这个文件以便BotCity Studio加载您的项目。在这个例子中,文件名将是“bot-sicalc.botproj”。然后,点击“打开”,然后点击“启动”。现在,您的项目已经成功加载到BotCity Studio中。

继续开发

在接下来的步骤中,我们将保持两个工具的打开状态,您的集成开发环境(IDE)和 BotCity Studio,以便在两个平台上同步代码。

到目前为止,我们只保留了以下代码在我的 "bot.py" 文件中。请注意,我们删除了 bot.browse("http://www.botcity.dev") 这行代码,因为它不再需要。

# 导入 Desktop Bot
from botcity.core import DesktopBot

# 导入与 BotCity Maestro SDK 集成需要的库
from botcity.maestro import *

# 若未连接到 Maestro SDK,则禁用错误报告
BotMaestroSDK.RAISE_NOT_CONNECTED = False

def main():

    bot = DesktopBot()


def not_found(label):
    print(f"Element not found: {label}")

if __name__ == '__main__':
    main()

保存这段代码到我的IDE中,在再次点击BotCity Studio时,您会注意到它也已经更新。

在bot = DesktopBot()这行的下面,我们要加入execute命令,让机器人打开Sicalc,代码如下:

bot.execute(r"C:\Program Files (x86)\Programas RFB\Sicalc Auto Atendimento\SicalcAA.exe")

一个有趣的建议是测试一下发生的情况是否符合预期。

例如,现在我们可以保存代码并通过IDE运行机器人来验证命令是否实际起作用。

尝试逐步进行测试,以便更好地理解发生的情况。这也会在发生错误时更容易理解。

如果这个步骤成功,机器人将会执行,并且Sicalc会显示在这个屏幕上:

例如,现在我们可以保存代码并通过IDE运行机器人来验证命令是否实际起作用。  尝试逐步进行测试,以便更好地理解发生的情况。这也会在发生错误时更容易理解。

💡 在继续之前,请确保将光标放在机器人在BotCity Studio中打开Sicalc的代码行的下方。这是因为它将开始为您的项目生成代码。代码将添加到光标所在的位置。

识别主屏弹出窗口

当我们第一次运行Sicalc应用程序时,会弹出一个包含警告的弹出窗口。我们的任务是识别这个窗口并立即关闭它。

我们将使用的策略是搜索一个锚点,并对“继续”按钮进行相对点击。

在BotCity Studio中,我们将光标定位在生成代码的那一行。

在UI选项卡中,我们点击要识别的元素附近,工具将放大以便我们选择元素。我们使用鼠标进行选择,点击并拖动以此方式进行选择:

识别主屏弹出窗口

💡 如果缩放不适合您进行所需的选择,只需在键盘上按下Esc键,然后再次点击元素附近即可重新选择。

在选择后,我们将填写Name字段为值"popup-esclarecimento"和Action字段为值"Click_relative"。"mode"字段应保持选择了"Image"选项。然后,我们点击提交按钮。

在选择后,我们将填写Name字段为值"popup-esclarecimento"和Action字段为值"Click_relative"。"mode"字段应保持选择了"Image"选项。然后,我们点击提交按钮。

点击"提交"后,当你拖动鼠标时,你会发现有一条红线随着移动。我们需要告诉BotCity Studio点击的相对位置。在这种情况下,位置是"继续"按钮。所以我们将鼠标光标拖动到该按钮上并点击它。

完成这个步骤后,BotCity Studio将生成以下代码段:

# 打开SiCalc应用程序
bot.execute(path_sicalc)

if not bot.find( "popup-esclarecimento", matching=0.97, waiting_time=10000):
    not_found("popup-esclarecimento")
bot.click_relative(195, 211)

记得在BotCity Studio中保存代码,可以使用快捷键"ctrl + s"。这将使您的IDE与生成的新代码同步更新。

在通过IDE再次运行此代码后,在打开Sicalc应用程序之后,机器人将对上面选择的元素执行相对点击操作。从那时起,我们可以继续填写DARF的过程。

选择菜单选项

在Sicalc应用程序中,我们需要访问菜单的“功能”选项,然后选择“填写DARF”选项。然后,我们需要对Sicalc屏幕进行新的截图,在BotCity Studio中,我们可以剪切这些元素。

我们先从“功能”项目开始。对于此选项,我们将命名为"funcoes",动作(action)将为点击(click)。模式(mode)选项应保持为图片(image)。

在Sicalc应用程序中,我们需要访问菜单的“功能”选项,然后选择“填写DARF”选项。然后,我们需要对Sicalc屏幕进行新的截图,在BotCity Studio中,我们可以剪切这些元素

在“功能”子菜单选项打开的情况下,让我们进行新的截图,以便我们可以选择并执行“填写DARF”选项的点击操作,将其命名为"preenchimento-darf"。

在“功能”子菜单选项打开的情况下,让我们进行新的截图,以便我们可以选择并执行“填写DARF”选项的点击操作,将其命名为"preenchimento-darf"。

BotCity Studio生成的代码将类似于以下代码:

if not bot.find( "funcoes", matching=0.97, waiting_time=10000):
    not_found("funcoes")
bot.click()

if not bot.find( "preenchimento-darf", matching=0.97, waiting_time=10000):
    not_found("preenchimento-darf")
bot.click()

填写初始表单

在前面的步骤之后,将打开一个初始表单,我们只需要填写税收代码。

再次,让我们对更新后的屏幕进行新的截图,以便我们可以在BotCity Studio中选择正确的元素。

在这种情况下,我们将找到税收代码输入框的锚点,并在其前面执行相对点击操作,以便进行填写:

填写初始表单

在找到并点击与该元素相关的字段后,我们使用paste()命令插入我们的数据。然后,我们将使用tab()命令跳转到下一个表单。

您可以直接在BotCity Studio中添加包含paste()和tab()命令的代码,并保存以更新到您的IDE中,或者直接通过IDE添加。只需记住同时保存代码以确保两个工具都得到更新。

下面是示例代码的一部分:

if not bot.find( "codigo-receita", matching=0.97, waiting_time=10000):
    not_found("codigo-receita")
bot.click_relative(128, 10)

# Inserindo no campo um código fictício
bot.paste("5629")

# Tecla "tab" avança para o próximo formulário
bot.tab()

填写DARF的数据

在执行上述代码后,将打开第二个表单。在这个表单中,我们需要填入DARF的其他数据。此时,屏幕将类似于以下内容:

执行上述代码后,将打开第二个表单

请根据实际情况进行适当的调整,并使用实际的截图文件名和数据来选择和填写相关字段。

更新BotCity Studio中的屏幕截图后,我们需要找到与计算期间(PA字段)和文件金额(以巴西货币表示的字段)相关的元素,并在其各自的字段上执行相对点击操作:

更新BotCity Studio中的屏幕截图后,我们需要找到与计算期间(PA字段)和文件金额(以巴西货币表示的字段)相关的元素,并在其各自的字段上执行相对点击操作

更新BotCity Studio中的屏幕截图后,我们需要找到与计算期间(PA字段)和文件金额(以巴西货币表示的字段)相关的元素,并在其各自的字段上执行相对点击操作

同样地,我们将使用框架的paste()命令来帮助我们在当前正在填写的字段中输入数值。请注意,在这个阶段,代码将如下所示:

if not bot.find( "periodo-apuracao", matching=0.97, waiting_time=10000):
    not_found("periodo-apuracao")
bot.click_relative(15, 25)
# Inserindo PA
bot.paste("310120")

if not bot.find( "valor", matching=0.97, waiting_time=10000):
    not_found("valor")
bot.click_relative(17, 27)
# Inserindo valor
bot.paste("10000")

下一步是点击"计算"按钮,以便我们可以进入最终的表单。有两种方法可以完成这一步骤。首先,我们可以添加enter()命令,因为在填写字段后按下回车键会触发"计算"按钮。

bot.enter()

另一种方法是通过计算机视觉和BotCity Studio的支持来解决。然后,我们进行新的截图,选择"计算"按钮,并指定动作为点击(click)。

请根据实际情况进行适当的调整,并使用实际的截图文件名来选择和点击"计算"按钮。

请根据实际情况进行适当的调整,并使用实际的截图文件名来选择和点击"计算"按钮。

if not bot.find( "calcular", matching=0.97, waiting_time=10000):
    not_found("calcular")
bot.click()

填写最终表单内容

在计算过程完成后,我们需要访问最终的表单。为此,我们将点击"DARF"按钮:

请根据实际情况进行适当的调整,并使用实际的截图文件名来选择和点击"DARF"按钮。

填写最终表单内容

if not bot.find( "botao-darf", matching=0.97, waiting_time=10000):
    not_found("botao-darf")
bot.click()

在打开最终表单后,让我们更新BotCity Studio中的屏幕截图,以便我们可以选择最后几个元素:

在打开最终表单后,让我们更新BotCity Studio中的屏幕截图,以便我们可以选择最后几个元素:

在这个阶段,我们将继续使用与之前步骤相同的策略,找到锚点并在需要填写的字段上进行相对点击操作。

我们需要在最后一个表单中填写以下数据:

姓名:Petrobras

电话:1199991234

CNPJ:33000167000101

参考:0

根据已经映射的所有锚点,生成的代码将类似于以下内容

if not bot.find("nome", matching=0.97, waiting_time=10000):
    not_found("nome")
bot.click_relative(0, 24)

# 在字段中插入姓名
bot.paste("Petrobras")

if not bot.find("telefone", matching=0.97, waiting_time=10000):
    not_found("telefone")
bot.click_relative(1, 27)

# 在字段中插入电话
bot.paste("1199991234")
if not bot.find("cnpj", matching=0.97, waiting_time=10000):
    not_found("cnpj")
bot.click_relative(123, 9)
# 在字段中插入CNPJ
bot.paste("33000167000101")
if not bot.find("referencia", matching=0.97, waiting_time=10000):
    not_found("referencia")
bot.click_relative(121, 8)
# 在字段中插入参考信息
bot.paste("0")

保存文件

最后一步是保存生成的DARF文件。在显示最后一个表单的屏幕上,填写完数据后,我们将点击"Imprimir"按钮:

点击"Imprimir"按钮:

if not bot.find( "imprimir", matching=0.97, waiting_time=10000):
    not_found("imprimir")
bot.click()

点击按钮后,如果没有直接配置打印机,则将打开Windows文件管理器窗口。

为了模拟这一行为,你可以使用以下代码:

点击按钮后,如果没有直接配置打印机,则将打开Windows文件管理器窗口。

在这种情况下,我们可以找到并点击窗口的引用,使其获得焦点:

在这种情况下,我们可以找到并点击窗口的引用,使其获得焦点:

在这之后,我们可以使用paste()来指定文件路径,并使用enter()来保存文件。以下是代码示例:

if not bot.find( "janela-salvar", matching=0.97, waiting_time=10000):
    not_found("janela-salvar")
bot.click()

# Inserindo o caminho do arquivo
bot.paste(r"C:\Users\username\Documents\DARF.pdf")
bot.enter()

完成保存文件后,我们的流程就结束了!

可以使用wait()命令等待2秒钟,以确保文件已保存,然后使用alt_f4()命令关闭表单和Sicalc窗口。

def main():
    bot = DesktopBot()

    # Implement here your logic...
    # Caminho onde está o executável SiCalc
    path_sicalc = r"C:\Program Files (x86)\Programas RFB\Sicalc Auto Atendimento\SicalcAA.exe"

    # Abre o aplicativo do SiCalc
    bot.execute(path_sicalc)

    if not bot.find( "popup-esclarecimento", matching=0.97, waiting_time=10000):
        not_found("popup-esclarecimento")
    bot.click_relative(195, 211)

    if not bot.find( "funcoes", matching=0.97, waiting_time=10000):
        not_found("funcoes")
    bot.click()

    if not bot.find( "preenchimento-darf", matching=0.97, waiting_time=10000):
        not_found("preenchimento-darf")
    bot.click()

    if not bot.find( "codigo-receita", matching=0.97, waiting_time=10000):
        not_found("codigo-receita")
    bot.click_relative(128, 10)

    # Inserindo no campo um código fictício
    bot.paste("5629")

    # Tecla "tab" avança para o próximo formulário
    bot.tab()

    if not bot.find( "periodo-apuracao", matching=0.97, waiting_time=10000):
        not_found("periodo-apuracao")
    bot.click_relative(15, 25)
    # Inserindo PA
    bot.paste("310120")

    if not bot.find( "valor", matching=0.97, waiting_time=10000):
        not_found("valor")
    bot.click_relative(17, 27)
    # Inserindo valor
    bot.paste("10000")

    if not bot.find( "calcular", matching=0.97, waiting_time=10000):
        not_found("calcular")
    bot.click()

    if not bot.find( "botao-darf", matching=0.97, waiting_time=10000):
        not_found("botao-darf")
    bot.click()

    if not bot.find( "nome", matching=0.97, waiting_time=10000):
        not_found("nome")
    bot.click_relative(0, 24)
    # Inserindo nome
    bot.paste("Petrobras")

    if not bot.find( "telefone", matching=0.97, waiting_time=10000):
        not_found("telefone")
    bot.click_relative(1, 27)
    # Inserindo telefone
    bot.paste("1199991234")

    if not bot.find( "cnpj", matching=0.97, waiting_time=10000):
        not_found("cnpj")
    bot.click_relative(123, 9)
    # Inserindo CNPJ
    bot.paste("33000167000101")

    if not bot.find( "referencia", matching=0.97, waiting_time=10000):
        not_found("referencia")
    bot.click_relative(121, 8)
    # Inserindo referência
    bot.paste("0")

    if not bot.find( "imprimir", matching=0.97, waiting_time=10000):
        not_found("imprimir")
    bot.click()

    if not bot.find( "janela-salvar", matching=0.97, waiting_time=10000):
        not_found("janela-salvar")
    bot.click()

    # Inserindo path do arquivo
    bot.paste(r"C:\Users\username\Documents\DARF.pdf")
    bot.enter()

    # Aguarda 2 segundos
    bot.wait(2000)

    # Fechando janela do formulário
    bot.alt_f4()

    # Fechando app do SiCalc
    bot.alt_f4()

def not_found(label):
    print(f"Element not found: {label}")

if __name__ == '__main__':
    main()

当然可以!桌面框架提供了多种命令,您可以探索和利用这些命令来构建桌面自动化。您可以在以下链接中查看完整的文档:BotCity 桌面框架文档(https://documentation.botcity.dev/pt/frameworks/desktop/)

在构建完自己的自动化流程后,为何不与社区分享您所学到的知识以及构建的机器人呢?只需将其分享给社区的机器人存储库即可。


文章来源地址https://www.toymoban.com/diary/share/325.html

其他相关:

什么是 RPA?

了解代码、无代码和低代码自动化

聊天机器人、机器人和RPA:它们有什么区别?

如何使用GitHub Actions来保持您的Python RPA项目更新

Hello World 的挑战:使用 BotCity 制作我的第一个 Python RPA 机器人

为什么在你的RPA项目中使用Python?

使用Python RPA构建与桌面系统交互的机器人


到此这篇关于使用Python RPA构建与桌面系统交互的机器人的文章就介绍到这了,更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

原文地址:https://www.toymoban.com/diary/share/325.html

如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用
上一篇 2023年09月23日 09:43
下一篇 2023年09月25日 09:21

相关文章

  • 如何使用OpenAI API和Python SDK构建自己的聊天机器人

    近日,OpenAI公司的ChatGPT模型走红网络。同时,OpenAI也推出了Chat API和gpt-3.5-turbo模型,让开发者能够更轻松地使用与ChatGPT类似的自然语言处理模型。 通过OpenAI API,我们可以使用gpt-3.5-turbo模型,实现多种任务,包括:撰写电子邮件或其他文本内容,编写Python代码,创建对话代

    2024年02月01日
    浏览(46)
  • 什么是RPA机器人?RPA机器人能做什么?RPA机器人的应用场景

    什么是RPA机器人? RPA机器人是一种使用软件机器人来模拟和执行人类操作的技术。RPA代表Robotic Process Automation(机器人流程自动化)。它是一种自动化技术,可以使用预定规则和预定流程来执行重复性、繁琐或规定任务的工作。 RPA机器人可以模拟人类的操作,并与计算机系统

    2024年02月10日
    浏览(50)
  • 什么是RPA机器人?RPA机器人能做什么?

    RPA机器人,全称Robotic Process Automation,即机器人流程自动化,是一种新型的自动化软件,可以模拟人类在计算机上执行的操作,进行重复性、繁琐的任务,提高工作效率和质量。 RPA机器人是一种基于人工智能和机器学习技术的自动化软件,它可以通过模拟人类在计算机上执行

    2024年02月03日
    浏览(51)
  • 【Python简单QQ机器人】使用nonebot2与go-cqhttp构建

    目录 一、前言 nonebot2-2.0.0b4 QQ机器人详细教程 二、准备 1.Python 2.Pycharm 3.nonebot2 4.go-cqhttp 三、配置 1.搭建go-cqhttp 2.创建nonebot2机器人 四、运行 五、nonebot2插件         闲着没事干,忽看到群里面的qq机器人,想要学习一下,用了两天实现了本体的搭建并添加了一些插件。期间

    2024年02月09日
    浏览(55)
  • LLM本地知识库问答系统(一):使用LangChain和LlamaIndex从零构建PDF聊天机器人指南

           随着大型语言模型(LLM)(如ChatGPT和GPT-4)的兴起,现在比以往任何时候都更容易构建比普通熊更智能的智能聊天机器人,并且可以浏览堆积如山的文档,为您的输入提供准确的响应。        在本系列中,我们将探索如何使用pre-trained的LLM创建一个聊天机器人,该聊

    2024年02月11日
    浏览(65)
  • RPA(机器人流程自动化)调研

    目录 概念 2022年最领先的5个RPA开源项目对比 Taskt 项目地址 优点 缺点 Robot Framework 项目地址 优点 缺点 TagUI 项目地址 优点 缺点 Open RPA 项目地址 优点 缺点 UI.Vision(Kantu) 项目地址 优点 缺点 Automagica 项目地址 优点 缺点 TagUI使用过程中遇到的问题 1、本地环境除了tagui的环境

    2024年02月04日
    浏览(77)
  • RPA与通知机器人的完美结合

    在现代快节奏的工作环境中,我们经常会面临多个任务同时进行的情况,你还在为时间不够用、忙碌而惆怅吗?你还在为时刻盯着电脑流程而烦恼吗?你还在为及时收不到自己的自动化任务进度而焦躁吗?别担心,RPA来帮你完成一切,下面让我们看看具体操作吧。 在钉钉获取

    2024年01月16日
    浏览(52)
  • RPA自动化中的机器人开发:如何开发机器人软件

    随着工业4.0时代的到来,企业对于提高生产效率、降低成本的需求越来越强烈,机器人自动化技术作为其中的一部分,逐渐被广泛应用。机器人自动化技术的其中一个分支——机器人软件,对于机器人的开发和应用具有重要的推动作用。本文旨在介绍如何进行机器人软件的开

    2024年02月13日
    浏览(57)
  • RPA机器人在电商领域有哪些应用?

    随着科技的不断发展,机器人流程自动化(RPA)已经成为许多领域的重要工具。在电商领域,RPA机器人也发挥了重要的作用。我将从两个方面探讨RPA机器人在电商领域的应用,以及它们如何提高电商运营的效率和效益。 1、订单处理 电商平台的订单处理是一项重要的任务,需

    2024年02月07日
    浏览(49)
  • RPA是什么样的机器人技术?RPA可以实现哪些流程的自动化?

    RPA(Robotic Process Automation)即机器人流程自动化,是一种通过模拟人类在计算机系统上的操作,实现流程自动化的技术。RPA机器人可以代替人工执行各种重复性任务,如数据输入、数据验证、文件整理、账单管理、客户服务等,帮助企业提高工作效率、减少错误、降低成本,

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包