Задать вопрос
@kotovone

Проблема с выводом парсера у Vk бота. Что делать?

Бот откликается на команды, кроме тех, где нужен парсинг сайтов погоды-времени. Как исправить ошибку?
vk_bot.py

import bs4 as bs4
import requests


class VkBot:

    def __init__(self, user_id):
        print("\nСоздан объект бота!")

        self._USER_ID = user_id
        self._USERNAME = self._get_user_name_from_vk_id(user_id)

        self._COMMANDS = ["ПРИВЕТ", "ПОГОДА", "ВРЕМЯ", "ПОКА"]

    def _get_user_name_from_vk_id(self, user_id):
        request = requests.get("https://vk.com/id"+str(user_id))
        bs = bs4.BeautifulSoup(request.text, "html.parser")

        user_name = self._clean_all_tag_from_str(bs.findAll("title")[0])

        return user_name.split()[0]

    def new_message(self, message):

        # Привет
        if message.upper() == self._COMMANDS[0]:
            return f"Привет-привет, {self._USERNAME}"

        # Погода
        elif message.upper() == self._COMMANDS[1]:
            return self._get_weather()

        # Время
        elif message.upper() == self._COMMANDS[2]:
            return self._get_time()

        # Пока
        elif message.upper() == self._COMMANDS[3]:
            return f"Пока-пока, {self._USERNAME}"

        else:
            return "Не понимаю о чем вы"

    def _clean_all_tag_from_str(self, message):
        pass # Автор не показал реализацию данного метода ;(

    def _get_weather(self):
        pass # Автор не показал реализацию данного метода ;(

    def _get_time(self):
        pass # Автор не показал реализацию данного метода ;(


Main.py

import random

import vk_api
from vk_api.longpoll import VkLongPoll, VkEventType

# --
# from commander.commander import commander
from vk_bot import VkBot
# --


def write_msg(user_id, message):
    vk.method('messages.send', {'user_id': user_id, 'message': message, 'random_id': random.randint(0, 2048)})


# API-ключ созданный ранее
token = ""

# Работа с сообщениями
vk = vk_api.VkApi(token=token)

# Работа с сообщениями
longpoll = VkLongPoll(vk)

commander = Commander()
print("Server started")
for event in longpoll.listen():

    if event.type == VkEventType.MESSAGE_NEW:

        if event.to_me:

            print(f'New message from {event.user_id}', end='')

            bot = VkBot(event.user_id)

            if event.text[0] == "/":
                write_msg(event.user_id, commander.do(event.text[1::]))
            else:
                write_msg(event.user_id, bot.new_message(event.text))

            print('Text: ', event.text)
            print('-' * 19)


Ошибка:
Traceback (most recent call last):
    File "Main.py", line 40, in <module>
        write_msg(event.user_id, bot.new_message(event.text))
    File "/path/to/vk_bot.py", line 31, in new_message
        return self.get_weather()
    File "/path/to/vK_bot.py", line 79, in _get_weather
        weather1 = p3[0].getText()
IndexError: list index out of range
  • Вопрос задан
  • 97 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
Vast-Nectarine
@Vast-Nectarine
Пишу очень плохой код
По ошибке видно, что массив p3 - пустой. Я не знаю, что хранится в p3, но, судя по всему, выполняется метод findAll.
Можно сделать вывод, что findAll ничего не смог найти.
Если честно, не морочьте голову и используйте openweathermap api для получения информации о погоде в каком-либо городе.
мои мысли

Приведите в порядок ваш код.
Вместо
request = requests.get("https://vk.com/id"+str(user_id))
используйте f-строки
request = requests.get(f"https://vk.com/id{user_id}")
Лучше вообще таким образом не получать данные о пользователе. Используйте этот метод, чтобы получить информацию о пользователях. (Также можно сохранять в базу данных, но что если пользователь поменяет имя?)

Используйте модуль logging, чтобы вести логи, а не использовать print.
Сделайте больше проверок, обрабатывайте ошибки:
1) Что если произойдет ошибка в
request = requests.get("https://vk.com/id"+str(user_id))
?
2) Что если сам long polling выдаст какую-нибудь ошибку?
3) Что если вам сразу напишут много людей?
import bs4 as bs4 Зачем? Достаточно import bs4
И по мелочи:
1) Используйте клавиатуру вместо команд ПРИВЕТ, ПОКА...
2) Вместо сложной конструкции:
vk.method('messages.send', ...)
Используйте
api = vk.get_api()
api.messages.send(user_id=user_id, message=message, random_id=random.randint(0, 2048))

3) Не называйте перменные как weather1 или p3. Почитайте про оформление кода.
4) lxml быстрее парсит HTML. soup = BeautifulSoup(some_html, 'lxml')
Его еще нужно установить pip install lxml Спасибо, Falconer

Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы