VK API на Python: часть 3, делаем чат-бота

В этой части туториала по VK API мы продолжим с помощью Python разбирать возможности ВК для разработчиков и сделаем небольшого чат-бота-автоответчика.

Бот будет выполнять некоторые действия в ответ на полученное сообщение. Например, отправлять в ответ на команду ~bash~, случайную цитату с bash.im. Для этого бота, кроме знаний питона и работы с VK API, нужны хотя бы начальные знания по парсингу. В данном случае нам понадобится requests + lxml.

Настройка

Прежде всего, нужно написать код для отлова нужных сообщений. Получать уведомления мы будем с помощью messages.get, используя last_message_id.

import vk
from time import sleep
from lxml import html
import requests as req

login = ''
password = ''
vk_id = 'ID_ВАШЕГО_ПРИЛОЖЕНИЯ'

session = vk.AuthSession(app_id=vk_id, user_login=login, user_password=password) 

vkapi = vk.API(session)

messages = vkapi.messages.get(count=1)
last = messages['items'][0]['id']

while True:
    try:
        messages = vkapi.messages.get(last_message_id=last)
    except Exception as e:
        print(e)
        sleep(4)
        continue
    if not messages['items']: # Если нет новых сообщений
        sleep(4)
        continue
    last = messages['items'][0]['id']
    for message in messages['items']:
        # временные заглушки
        if "~bash~" in message['body']:
            print("Wow. Such bash")
        if "~cgra~" in message['body']:
            print("Very nice")
    sleep(4)

Парсим Баш

Теперь нужно написать функции для получения цитаты из Баша.

def bash(id):
    try:
        r = req.get('http://bash.im/random')
        doc = html.document_fromstring(r.text)
        bash = '\n'.join(doc.xpath('//*[@id="body"]/div[3]/div[@class="text"]/text()'))
        vkapi.messages.send(user_id=id, message=bash)
    except Exception as e:
        print(e)

С помощью XPath мы получаем текст из контейнера div, содержащий в себе первую цитату на странице. Найти путь нужный вам элемент можно в инструментах разработчика вашего браузера, но почти всегда понадобится «допилить» до нужного вида и убрать лишние теги, вроде <br/>.

Исправим цикл проверки сообщений, заменив заглушку на готовую функцию:

     ...
        if "~bash~" in message['body']:
            bash(message['user_id'])
     ...

Сейчас все должно работать. Но есть одно но. Если кто-то в коллективном чате напишет ~bash~, то цитата отправится к нему в личные сообщения, а не в общий чат. Надо поправить.

def bash(id, mode='u'):
    try:
        r = req.get('http://bash.im/random')
        doc = html.document_fromstring(r.text)
        bash = '\n'.join(doc.xpath('//*[@id="body"]/div[3]/div[@class="text"]/text()'))
        if mode == 'c':
            vkapi.messages.send(chat_id=id, message=bash)
        else:
           vkapi.messages.send(user_id=id, message=bash)
    except Exception as e:
        print(e)


        ....
        if "~bash~" in message['body']:
            if 'chat_id' in message:
                bash(message['chat_id'], 'c')
            else:
                bash(message['user_id'])
        ....

Интерфейс пользователя

На основе этого парсера можно приготовить свой собственный, для любимого ресурса. Но давайте добавим еще немного функционала к нашей программе.

def print_help(id, mode='u'):
    try:
        message = """=== VK-бот ===
        Доступные команды:
        &#_9989; ~bash~ -- случайная цитата с bash.im 
        &#_9989; ~help~ -- показать помощь"""
        if mode == 'c':
            vkapi.messages.send(chat_id=id, message=message)
        else:
           vkapi.messages.send(user_id=id, message=message)
    except Exception as e:
        print(e)

        ...
        if "~help~" in message['body']:
            if 'chat_id' in message:
                print_help(message['chat_id'], 'c')
            else:
                print_help(message['user_id'])
        ...

Таким образом, набор доступных команд можно будет расширить в соответствие с функциями, которые вы добавите к парсеру или не только к нему.

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Go-разработчик
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ