• Ошибка в colorsys python?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    В ошибке же прямым текстом написано: необходим integer, а не число с плавающей точкой
    Ответ написан
    1 комментарий
  • Как привязать скрипт python к окну игры?

    @Aress9
    Задача не такая уж и простая, но реализовать возможно.

    Я дам описание как я сделал нажатие клавиши в блокноте. Для ваших задач вы должны сами придумать реализацию.

    Первое что понадобиться сделать, это получить идентификатор окна для дальнейшего с ним взаимодействия. Используем функцию FindWindow передавая первым параметром None, а вторым заголовок окна, его можно посмотреть используя Spy++ или WinSpy++.
    hwnd = win32gui.FindWindow(None, "Безымянный – Блокнот")

    Второе, найти класс окна, куда требуется отсылать сообщения (вам возможно не понадобится). Для этого используем функцию FindWindowEx. В моём случае требуется подкласс "Edit", его название также можно получить с помощью WinSpy++.
    editClass = win32gui.FindWindowEx(hwnd, None, "Edit", None)

    Чтобы отправить сообщение о каком-либо действии в окно, используйте функцию SendMessage. Передавая ему идентификатор класса, само действие, и дополнительные к нему параметры(подробнее смотрите в документации к WinApi). Просто отправить команду может не сработать, в таком случае проследите сообщения вводимые вами в окно с помощью Spy++.
    win32gui.SendMessage(editClass, win32con.WM_CHAR, 0x7A, 0) #Ввод символа 'z' в класс "Edit"


    Весь мой код:
    import win32gui
    import win32con
    
    hwnd = win32gui.FindWindow(None, "Безымянный – Блокнот")
    editClass = win32gui.FindWindowEx(hwnd, None, "Edit", None)
    win32gui.SendMessage(editClass, win32con.WM_CHAR, 0x7A, 0)
    Ответ написан
    Комментировать
  • Как получить несколько элементов с помощью XPath?

    DevMan
    @DevMan
    код скрином - это ебланство моветон. потому что не скопировать для теста, а набирать будет только лось.
    это раз.

    а два - вас в логические операторы не учили?

    типо так, не проверял: //div[@class = ("element1", "element2")] зависит от версии xpath.
    Ответ написан
    3 комментария
  • (aiogram) Как запретить доступ к инлайн кнопке другим пользователям кроме указанного?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    return user1
    вот это вообще не понял

    Помещаете username пользователей в callback_data. В обработчике достаете их username из data и сравниваете с нажавшим кнопку.

    @dp.message_handler(commands="ruletkaid")
    async def inlinebtn(message: types.Message):
        user1 = message.get_args()
        user2 = message.from_user.username
        keyboard = types.InlineKeyboardMarkup()
        keyboard.add(types.InlineKeyboardButton(text="Принять", callback_data=f"accept_{user1}:{user2}"))
        keyboard.add(types.InlineKeyboardButton(text="Не принимать", callback_data=f"decline_{user1}:{user2}"))
        await message.answer(user1 + ', вас вызывает на дуэль ' + user2, reply_markup=keyboard)
    
    
    @dp.callback_query_handler(lambda call: call.data.startswith('accept_'))
    async def accept_duel(call: types.CallbackQuery):
    
        user1, user2 = call.data.replace('accept_', '', 1).split(':')
    
        if call.from_user.username != user1:
            await call.answer(text="Не тебе адресовано.", show_alert=True)


    Не проверял, но, по идее, работает
    Ответ написан
    Комментировать
  • Срабатывает не тот if который должен, что не так?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    if int(b) > int(a):
    Ответ написан
    1 комментарий
  • Python | PyAutoGUI | Как сделать активацию по нажатии клавиши?

    @MrMiquy
    Вы можете использовать библиотеку Keyboard.
    Её можно загрузить через комманду pip install keyboard. Чтобы всё время проверять нажата ли определённая клавиша:

    import keyboard
    
    key = 'a'
    
    while True:
        if keyboard.is_pressed(key)
            print('Нажата клавиша: ' + key)


    Вместо "а" может быть любая другая латинская буква (Или такие клавиши как: {'alt', 'alt gr', 'ctrl', 'left alt', 'left ctrl', 'left shift', 'left windows', 'right alt', 'right ctrl', 'right shift', 'right windows', 'shift', 'windows'} )

    Можете прочитать больше информации отсюда: https://github.com/boppreh/keyboard
    Ответ написан
    2 комментария
  • Расширение таблицы при парсинге?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    В общем, рассказываю про парсинг.

    Код, который видно на странице через инспектор элементов в браузере - это код, который браузер подготовил для пользователя. Открываете сайт - браузер отправлять запрос на сервер. Запрос состоит из метода, пути, заголовков и тела. После первоначального запроса браузер получает от сервера HTML страницу, в которую включено (обычно) множество JS скриптов, которые в процессе выполнения могут создавать дополнительные запросы на сервер для получения дополнительной информации. После выполнения всех действий, пользователь видит в браузере готовый результат, который отличается от первоначального запроса из-за дополнительных джаваскриптов.

    Если элемент (класс, id, и тд) видно в инспекторе браузера - это не означает, что элемент присутствовал при первоначальном запросе. Чтобы увидеть тот код, который браузер получает первоначально (тот самый код, который вы получите через requests, curl итд) - нужно нажать CTRL+U, либо правой кнопкой -> просмотр кода страницы
    Это - тот самый код, который вы получаете, и все данные нужно искать только в нем, это дает гарантию того, что нужный вам элемент будет присутствовать при выполнении запросов через ЯП.

    Если нужного элемента нет на странице, значит он загружен каким нибудь JS скриптом. Здесь будут два варианта:
    1. JS отправляет дополнительный запрос на сервер, получает нужные данные и вставляет их в HTML.
    2. Данные создаются внутри JS скрипта без запросов (очень маловероятно)

    Если данные появляются в результате дополнительного запроса, то нужно просто повторить этот запрос.

    Чтобы понять, что нужно - нужно воспользоваться любым сниффером трафика. Самое простое - встроенный в браузер логгер запросов. F12 -> Network.
    6124fec4cfd69347854863.png
    Обычно достаточно поставить фильтр на XHR.
    Если есть под рукой Fiddler, то тоже сгодится. Ну и Burp / ZAP как вариант (но очень жирно).

    Алгоритм будет примерно таким:
    1. Открываем вкладку Network
    2. Очищаем историю запросов (если есть)
    3. Желательно поставить галочку "Preserve log", чтобы история не пропадала.
    4. Обновляем страницу. Если контент подгружается при прокретке / по нажатию кнопки - крутим / нажимаем и тд.
    5. Теперь можно нажать CTRL+F все в той же вкладке Network и вписать искомый текст (допустим название товара).
    6. Слева будут те запросы, которые содержат эту подстроку. Теперь нужно просто пощелкать по ним, найти нужный, посмотреть из чего он состоит и повторить его через requests.

    Нужно обратить внимание на заголовки и тело запроса. Не редко при загрузке доп. информации в тело запроса так же передается указатель текущей страницы, или индекс элемента, с которого начинается новый список. Так же в заголовки могут добавиться дополнительные. Например, csrf token, либо X-Requested-With. Если повторение запроса не принесло желанный результат - стоит проверить заголовки и тело еще раз. Если сайт загружает данные при нажатии на кнопки, прокрутке страницы и тд - алгоритм тот же.

    Делюсь хорошим сайтом, который увидел тут: https://curl.trillworks.com/
    Копируете свой запрос как CURL
    612500b91076a776091384.png
    Затем вставляете на сайт. Он выдаст готовый код на Python. Но нужно понимать, что это автоматический процесс и он не всегда выдает правильный результат. В частности, преобразование application/json тела довольно неправильно. Но для копипаста некоторых заголовков подходит вполне. В общем сайтом пользоваться можно, но и самому думать тоже нужно

    Из хороших программ - Postman. Позволит легко и быстро составлять запросы, есть экспорт в Python код. Советую, если запросы довольно тяжелые, чтобы составлять их "наживую".

    Краткая выжимка:
    1. Код через инспектор браузера != коду с запроса requests / curl.
    2. Скорее всего нужные вам данные подгружаются доп. запросами, ищутся через любой мониторинг трафика.
    3. Следите за телом и заголовками запроса. Заголовки, даже самые незначительные, могут влиять на конечный результат.
    4. Старайтесь всегда в заголовки добавлять User-Agent

    Если данные грузятся без доп запросов, лежат в неизвестном формате, или просто лень разбираться - используйте Selenium. Он является таким же браузером, но только с возможностью контролировать его работу
    Ответ написан
    3 комментария
  • Как создать бота в телеграме для учета рабочего времени?

    @MEDIOFF
    Python Developer
    Предлагаю покапать вот в эту сторону
    Ответ написан
    Комментировать
  • Как получить имя 2 юзера через ответ на сообщение?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Поле reply_to_message у класса Message содержит информацию о сообщении, на которое отвечают. Ну или None, если это обычное сообщение.
    Ответ написан
    2 комментария
  • Почему не обновляется картинка в телеграм бот?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Скорее всего телеграм кэширует запрос и потом использует фото из кэша. Просто загрузите файл и потом отправьте

    import requests
    
    r = requests.get('https://thiscatdoesnotexist.com')
    with open('image_temp.jpg', 'wb') as f:
        f.write(r.content)
    bot.send_photo(message.chat.id, open('image_temp.jpg', 'rb'))


    Можно и без сохранения файла, конечно,
    import requests
    from PIL import Image
    import io
    
    r = requests.get('https://thiscatdoesnotexist.com')
    bot.send_photo(message.chat.id, Image.open(io.BytesIO(r.content)))
    Ответ написан
    3 комментария
  • Как дать боту возможность одновременно ждать сообщения от пользователя и проверять время для запланированного вывода сообщения?

    @RINAMI
    Занимаюсь монтажом и дизайном. PSD,AEX,VEG.
    Для того чтобы планировать задачи для своего кода, нужен schedule
    Пример:
    import schedule
    def primer():
          #func options
         schedule.every().day.at('8:00').do(primer)
         while True:
                schedule.run_pending()
                time.sleep(3)


    Чтобы бот делал все как вы хотите, создайте два потока пример:
    import threading
    from threading import Thread
    def thread2():
          thr2 = Thread(target=primer)
          thr2.start()


    В конец кода добавьте:
    if __name__ == '__main__':
        thread2()


    Итог:
    Функции которые вам нужны, будут выполнятся в основном потоке, а в потоке номер 2 будет выполнятся schedule.
    Ответ написан
    Комментировать
  • Скрипт для генерации уникальных изображений?

    MinTnt
    @MinTnt
    Думаю тут и PIL сгодится. Сначала задав код для рисования по пиксельно нужного изображения. А дальше создать список с разными цветами, с которого потом через random выбирать нужный цвет.

    Т.е. создать по функции для рисования определёных одноцветных мест рисунка. А далее выбирая через random случайный код света, передавать его функции, для отрисовки.

    Update: я пока лишь так, быстро просмотрел PIL, написал пусть и не до конца идеальный, но для начала сойдёт - мини-код. Он берёт из папки уже существующее входное изображение, а на выходе изменённое со случайными цветами.
    from PIL import Image, ImageDraw 
    from random import randint
    import time
    
    image = Image.open('enter-image.png')
    pix = image.load()
    width = image.size[0]
    height = image.size[1]
    draw = ImageDraw.Draw(image)
    
    pixel_id = []
    print(f'Через 3 секунды начнётся анализ картинки. Размеры {width}x{height}')
    time.sleep(3)
    start_time = time.time()
    
    for x in range(width):
    	for y in range(height):
    		print(x, y)
    		if not pix[x,y] in [i[0] for i in pixel_id]:
    			pixel_id.append([pix[x,y], []])
    		pixel_id[[i[0] for i in pixel_id].index(pix[x,y])][1].append((x,y))
    
    for a in pixel_id:
    	color = (randint(0, 255), randint(0, 255) , randint(0, 255))
    	for draw_zone in a[1]:
    		draw.point(draw_zone, color)
    
    print('Проработка изменённой картинки завершена. Начинается сохранение.')
    image.save("output-image.png")
    print(f'Сохранение завершено за {time.time()-start_time}.')

    Если же нужно чтоб какие-то цвета не брало в счёт, можно приделать такую проверку.
    if pix[x,y] not in [(0, 0, 0, 255), (255,255,255, 255)]:
    			if not pix[x,y] in [i[0] for i in pixel_id]:
    				pixel_id.append([pix[x,y], []])
    			pixel_id[[i[0] for i in pixel_id].index(pix[x,y])][1].append((x,y))
    Ответ написан
    7 комментариев
  • Как складывать несколько одинаковых элементов в списке?

    0xD34F
    @0xD34F
    def sum_items(arr):
      result = {}
    
      for item in arr:
        v, k = int(item[:-1]), item[-1]
        result[k] = result.get(k, 0) + v
    
      return [ str(v) + k for k, v in result.items() ]
    Ответ написан
    Комментировать
  • Отредактировать текст поста в своем телеграм канале?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Вообще говоря, правильно отслеживать ботом публикации и запоминать id, например, в базу. Но так-то можно найти в клиенте пост, и сделать копирование ссылки на пост в меню, она будет иметь вид:

    https://t.me/my_awesome_channel/message_id

    Bot API не позволяет прочитать историю, боты видят только новые публикации. Если ручной способ не подходит (например, постов слишком много для ручной работы), придётся пилить бота на клиентском MTProto API (telethon, pyrogram).
    Ответ написан
    Комментировать
  • Как упростить код inline кнопок?

    @twistfire92
    Python backend developer
    инициализацию и добавление кнопок tr9 - tr16 можно упростить так:

    buttons = []
    for number in range(9, 17):
        buttons.append(InlineKeyboardButton(f"{s[number][0]}", callback_data=f"tr{number+1}"))
    
    ........
    
    tradeee.add(*buttons)


    Пагинацию можешь сам надумать. Я бы в отдельную функцию вывел заполнение кнопочной разметки. Параметром туда передаешь "номер страницы", от этого и пляшешь.
    Ответ написан
    9 комментариев