Задать вопрос
  • HTML-страницы в Python (pycharm) с использованием разных библиотек не весь по сравнению если смотреть в самом браузере?

    Vindicar
    @Vindicar
    RTFM!
    Наверняка основной запрос отдаёт болванку, а часть контента подтягивается отдельно яваскриптом и уже в эту болванку вставляется. Поищи по этому сайту, уже спрашивали как парсить динамический сайт.
    Ответ написан
  • Как передать апдейт телеграм боту о том что парсер обновил БД?

    Vindicar
    @Vindicar
    RTFM!
    Вариантов много. Самый простой - храни в БД время обновления (например, время, когда была добавлена запись), и пусть его бот периодически проверяет. Хорошо работает в том плане, что БД может обновляться разными источниками, бот о них знать не обязан. Но вносит лаг между обновлением данных и реакцией бота. Да и бот базу понапрасну дергает.

    Так как в тегах postgre, почитай про команду NOTIFY. Она вроде примерно про то же самое.

    Также есть вариант с сокетом - бот слушает UDP-сокет, парсер на него посылает пакет с оповещением. Плюс в том, что оповещать может любая программа, которая может до этого сокета достучаться.
    Ответ написан
    1 комментарий
  • Ошибка TypeError: marks_message() missing 1 required positional argument: 'marks' почему?

    Vindicar
    @Vindicar
    RTFM!
    @bot.message_handler(content_types=['text'])
    def marks_message(message, marks):


    marks_message(message, marks)
    Плохая идея. Ты уже решай - или функция является обработчиком события от бота, и тогда её параметры определяются библиотекой, или функция вызывается тобой.
    Ответ написан
    7 комментариев
  • Почему приложение Flask не работает в классе?

    Vindicar
    @Vindicar
    RTFM!
    Чтобы понять, нужно понимать три вещи про питон.
    Во-первых, в нём всё - оператор. Да-да.
    def - это оператор объявления функции.
    class - оператор объявления класса.
    Тебе никто не запрещает сделать
    if condition:
        def foo():
            pass
    else:
        def bar():
            pass


    Во-вторых, все методы класса существуют на уровне класса. Явная передача self на это намекает.
    Иными словами:
    class Foo:
        def bar(self, baz):
            print(self, baz)
    
    foo = Foo()
    # вот этот вызов
    foo.bar('hallo!')
    # полностью эквивалентен вот этому
    Foo.bar(foo, 'hallo!')

    А когда ты обращаешься к foo.bar, Питон конструирует специальный временный объект-обёртку, который ссылается на Foo.bar(), но в то же время подставляет туда первым параметром тот объект foo, к которому произошло обращение. Так что если Foo.bar() принимает два параметра (self и baz), то foo.bar() принимает уже один (baz), так как правильный self будет подставлен этой обёрткой самостоятельно.

    В-третьих, декоратор - это просто синтаксический сахар для вызова функции. Иными словами:
    @app.route('/') 
    def index(self):
        return render_template('index.html')

    будет эквивалентно вот такому коду:
    def index(self):
        return render_template('index.html')
    
    _decorator = app.route('/')
    index = _decorator(index)

    Причем это будет работать одинаково и вне класса, и внутри класса.
    Как это относится к твоему вопросу? А вот как.
    class Web:
        app = Flask(__name__) 
    
        @app.route('/') 
        def index(self):
            return render_template('index.html')

    Последовательность действий тут такова:
    1. Создаётся пространство имён для нового класса, пока что безымянного.
    2. В этом пространстве имён создаётся переменная app, её выражение вычисляется немедленно
    3. В этом пространстве имён создаётся функция index()
    4. Отрабатывает декоратор @app.route(), и регистрирует эту функцию index() как обработчик запроса. Обрати внимание, ни функция index(), ни @app.route понятия не имеют, что index() находится внутри класса! Поэтому app.route не ожидает, что index() будет первым параметром принимать какой-то там self. Как следствие, вместо self функция index() получит то, что передал первым параметром Flask. В данному случае - ничего, так как у тебя роут без параметров.
    5. Ну и в итоге отрабатывает создание класса, с учётом указанных предков (у тебя это неявно указанный object), наполнения пространства имён, и пр. Этот класс потом присваивается переменной Web в вышележащем пространстве имён.

    Ну и как теперь жить?
    А очень просто. Если тебе вот позарезу нужны обработчики роутов в виде методов класса, можно сделать так:
    class Web:
        def __init__(self):
            self.app = Flask(__name__) 
            # получаем обёртку для метода, привязанную к нашему self, см. пункт 2
            self_index = self.index
            # вызываем декоратор вручную, см. пункт 3.
            decorator = self.app.route('/')
            decorator(self_index)
            # ну или то же самое в одну строку:
            self.app.route('/')(self.index)
    
        def index(self):
            return render_template('index.html')

    Разумеется, это не очень удобно. Можно попробовать схитрить, написав свой декоратор, который помечает методы класса ассоциированным роутом, а в конструкторе экземпляра найти все помеченные методы и скормить их фласку одним списком.
    Но я почти уверен, что такой механизм уже кем-то реализован, просто надо поискать... ну или забить на класс, если от него нет выигрыша.
    Ответ написан
    Комментировать
  • Как реализовать генерацию всех комбинаций пароля по маске?

    Vindicar
    @Vindicar
    RTFM!
    Очень просто. Смотри на первый пример:
    product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    Генерятся комбинации из двух символов (так как два параметра). Причем первый параметр кодирует возможные первые символы, а второй - возможные вторые.

    Нам нужно только обобщить это.

    Идешь циклом по строке-маске и формируешь список, где каждый элемент - список подставляемых знаков, соответствующих текущему символу строки-маски. (Назовём этот список списков parts).
    А дальше просто делаешь цикл for combo in product(*parts):
    Ответ написан
    1 комментарий
  • Как обработать исключение в генераторе функции filter?

    Vindicar
    @Vindicar
    RTFM!
    А чем не устроило:
    text_lower = text.lower() # зачем сто раз преобразовывать?
    for x in list_words:
        if x.lower() in text:
            finder = x
    else:  # else относится к for, а не к if
        finder = None
    Ответ написан
  • Как вызвать функцию aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Ну у тебя тут сразу три проблемы.
    1. Искомая функция - обработчик событий в боте. Она ожидает, что на момент её вызова вся нутрянка бота будет в рабочем состоянии. Я сомневаюсь, что твой код это обеспечивает.
    2. Функция ожидает первым параметром объект класса types.Message. Обычно такие объекты создаёт сама библиотека aiogram, на основании приходящих боту сообщений. Программа их создавать не должна.
    3. Вызываемая функция асинхронная (async), а вызывающий её код - синхронный. Вызвать её будет не так просто, особенно с учётом пункта 1. Вдвойне так, если ты не в курсе, в чём разница между синхронным и асинхронным кодом.

    Так что вывод: ты творишь полную фигню. Сформулируй, какую задачу ты пытаешься решить, тогда может, тебе подскажут, как это сделать.
    Ответ написан
    Комментировать
  • Как запарсить div class (mamba)?

    Vindicar
    @Vindicar
    RTFM!
    pphhpphh, поучи немножко, как веб работает, перед тем как парсеры писать. Сэкономишь кучу времени потом.
    Сейчас далеко не 90е, и на большинстве страниц полно JS-скриптов. Они, в том числе, могут делать фоновые (без перезагрузки страницы) запросы по ходу работы сайта. Так, например, реализуется "бесконечная лента" - по достижению низа страницы делается фоновый запрос, и новый контент подставляется вниз.
    Некоторые сайты на этом вообще целиком построены - отдают основным запросом только болванку, а содержимое туда подсовывают фоновыми запросами. Как следствие, то, что ты выкачиваешь через requests, и то, что увидит пользователь в браузере - две большие разницы.
    Соответственно, тут нужно:
    1. Идентифицировать, какие фоновые запросы делает сайт. Инструменты разработчика в браузере в помощь.
    2. Определить, какие из этих запросов подгружают нужную тебе информацию, и в каком виде она представлена. Нередко там не HTML-разметка, а формат JSON, с которым куда проще работать.
    3. Определить, что нужно для выполнения этих запросов: какие URL дёргать, какие параметры подставлять, и т.д.
    4. Попробовать имитировать только эти запросы.
    Успех зависит от сайта, многие пытаются защищаться от такого, кто во что горазд.

    Альтернативный вариант - использовать безголовый браузер. Но там своя гора проблем: это куда более ресурсоёмко, нужно дождаться полной прогрузки сайта, API для поиска там тоже своё. Так что я бы переходил к этому варианту только если имитировать запросы самому не вышло.
    Ответ написан
    Комментировать
  • Почему не принимает сообщение?

    Vindicar
    @Vindicar
    RTFM!
    text=(int)
    Это не будет работать.
    Учи, как пользоваться реализацией FSM (finite state machine) в aiogram.
    Ответ написан
    Комментировать
  • Как остановить поток python?

    Vindicar
    @Vindicar
    RTFM!
    Метод join() приостанавливает тот поток, в котором он вызван до момента завершения указанного потока. Он никак не сигнализирует указанному потоку, что пора завершаться, это твоя задача.
    Я не вижу, чтобы ты присваивал True переменной schedule_stop.
    Ответ написан
    2 комментария
  • Как обойти бинарное дерево?

    Vindicar
    @Vindicar
    RTFM!
    Для именно такой структуры данных - нет, нельзя.
    (Ну, можно попробовать рекурсией, но это извращение будет.)
    Ответ написан
    5 комментариев
  • Как сделать, чтобы телеграм бот принимал обрабатывал сообщение по команде?

    Vindicar
    @Vindicar
    RTFM!
    человек вводил команду(/start например), после этого бот просил написать что нибудь, человек писал какой то текст и бот что то делал с ним

    Тебе нужны Finite State Machines (автоматы состояний). Стоит почитать, что это вообще такое.
    Проблема в том, что в pyTelegramBotAPI их реализации из коробки вроде нет. Есть сторонние библиотеки, которые нужно искать. Ну или реализовывать самому.

    Идея, в общем-то, простая: тебе нужно для каждого пользователя хранить его текущее состояние (например, ввёл он команду /start или нет). Тогда в обработчике сообщения ты сможешь узнать состояние этого пользователя, и решить, что делать с этим сообщением.
    Сложности будут, когда тебе потребуется хранить какие-то ещё данные вместе с сообщением.
    Ответ написан
    Комментировать
  • Как искать процесс с помощью регулярного выражения?

    Vindicar
    @Vindicar
    RTFM!
    Ну так почитай, как пользоваться регулярными выражениями.

    Создаёшь объект регулярки по твоему шаблону с помощью re.compile(), потом у этого объекта вызываешь метод match(), чтобы проверить совпадение строки с этим шаблоном. Если match() вернул не None - строка совпала.
    Ответ написан
  • Как отсортировать QuerySet по значению ForeignKey?

    Vindicar
    @Vindicar
    RTFM!
    Конкретно с Django ORM я не работал, но общая идея простая: сделай join списка товаров с ценами в магазине с дополнительным условием - id магазина совпадает с заданным.
    Тогда получишь выборку только тех товаров, которые есть в заданном магазине, и их цен.
    Ответ написан
    Комментировать
  • Не работает условие Python, SQLite как решить и почему?

    Vindicar
    @Vindicar
    RTFM!
    1. chat_verification = {message.chat.id}
    chat_verification - это множество из одного элемента, вместо простого значения. Зачем?
    2.
    cursor.execute(f"SELECT chat_id FROM chat_id_table WHERE chat_id ='{chat_verification}' AND verification = 1")

    Никогда не используй f-строки. С целыми числами прокатит, со строками - очень рискованно. Используй подстановку параметров.
    cursor.execute("SELECT chat_id FROM chat_id_table WHERE chat_id = ? AND verification = 1", (message.chat.id, ))

    3.
    check = cursor.execute(...
    if check is True:

    execute() вернёт ссылку на всё тот же cursor, независимо от запроса. Тебе нужно выбрать строку из этого курсора с помощью метода fetchone(). Метод вернёт или кортеж с одним значением chat_id, или None, если ни одна строка не удовлетворяет условию.
    cursor.execute("SELECT chat_id FROM chat_id_table WHERE chat_id = ? AND verification = 1", (message.chat.id, ))
    result = cursor.fetchone()
    if result is None:
        print('Нет такой строки')
    else:
        chat_id = result[0]
        print('есть результат:', chat_id)
    Ответ написан
  • Как вывести данные из массива в сообщение?

    Vindicar
    @Vindicar
    RTFM!
    for product in select_db():
        @dp.callback_query_handler(text=product['name_but'])
        async def pole(message: types.message):
            await bot.send_message(message.from_user.id, product['desk'], reply_markup=but.nav_button)

    Ты делаешь глупость.
    Просто потому, что после того, как этот код отработает, созданные тобой копии обработчика pole() останутся, и будут мешать.
    Используй один, более общий обработчик callback_query_handler, и в нём уже смотри, какой текст тебе пришёл, какой пользователь его отправил, и что с этим текстом надо делать.
    Ответ написан
    1 комментарий
  • Как сделать условие в SQLite Python?

    Vindicar
    @Vindicar
    RTFM!
    Ну так у тебя второй запрос запршивает всех пользователей, без условия.
    А вообще приведённый код не имеет смысла и не должен работать вообще никак.
    for i in cursor.fetchone("SELECT ID FROM user_info WHERE RANK = '1'"):

    Ты перебираешь столбцы в первой строке (fetchone), для которой RANK = '1'. Это при том, что запрос возвращает тебе только один столбец - ID. А ещё метод fetchone() не принимает параметров. Ты пропустил вызов execute()?

    Потом ты почему-то берёшь 0й символ этого столбца. Если он равен 1 (а он не будет равен 1, так как это символ, а не число).
    Потом ты перебираешь всех пользователей, и отправляешь им сообщения (при этом у тебя в вызове send_message() две опечатки - в имени переменной и незакрытая скобка).

    А ещё у тебя отступы кривые - почему for i с отступом?

    В общем, по такой бредятине понять, в чём дело, нереально.
    Ответ написан
    4 комментария
  • Возможно ли сделать обработку кнопки в сокете на python?

    Vindicar
    @Vindicar
    RTFM!
    WOLF3252, ты не понимаешь как работает Tkinter, для начала.
    tkinter.Button(btn_0)
    Ты попытался создать новую кнопку, передав её в качестве родителя какую-то строку (а нужно передать родительский виджет), и тут же эту кнопку выбросил, ничего с ней не сделав. Вместо того, чтобы конфигурировать (configure()) уже существующую кнопку.
    А то я думал, что только текст передавать можно

    Через сокеты можно передавать только поток байт. И точка.
    Фокус в том, как ты этот поток байт интерпретируешь, т.е. какой у тебя протокол передачи данных. Например, ты можешь решить, что будешь передавать два числа (известного размера в байтах), где первое число - номер кнопки, второе - номер цвета в некотором списке. По нажатию кнопки одна сторона сформирует и отправит эту пару чисел, а другая, увидев, что поступили новые данные, их примет, прочитает и интерпретирует. Это будет очень простой протокол, но он будет работать.

    Главная сложность в таких приложениях в другом. По умолчанию сетевые операции останавливаются (блокируют поток) на время своего выполнения. Т.е. если тебе не передали данные, а ты вызвал recv() - программа не вернётся из recv() пока данные не придут или пока соединение не разорвётся.
    А оконным приложениям для работы нужен непрерывно работающий цикл обработки действий пользователя, им нельзя "задумываться", иначе приложение на вид "зависает". Бороться с этим можно разными способами, я бы посоветовал освоить функцию select(), чтобы заранее (до вызова recv()) понять, есть ли непрочитанные данные или нет.
    Ответ написан
    Комментировать
  • Как конвертировать числа в формат доллара?

    Vindicar
    @Vindicar
    RTFM!
    >>> import locale
    >>> locale.setlocale(0, 'en-us')
    'en-us'
    >>> locale.currency(123400/100)
    '$1234.00'
    >>> locale.currency(123400/100, grouping=True)
    '$1,234.00'
    >>>
    Ответ написан
    Комментировать
  • Как поменять начало координат на выделеной области cv2?

    Vindicar
    @Vindicar
    RTFM!
    Не очень понятно, что ты имеешь ввиду. cv2 всегда сообщает клики в координатах окна. Они, как правило, совпадают с координатами внутри показанного в окне изображения: та же точка отсчёта, то же направление осей, масштаб 1:1. Единственное отличие - если ты увеличил размер окна, клик может оказаться за пределами показанного изображения.

    Если тебе нужна другая координатная система, пересчитывай координаты сам.
    Ответ написан
    Комментировать