Ответы пользователя по тегу Python
  • Как проверить доступность списка IP:Port из txt файла?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    С помощью psping: https://learn.microsoft.com/en-us/sysinternals/dow... By Mark Russinovich.
    import subprocess
    
    
    # Функция для проверки доступности IP:port с помощью psping
    def check_ip(ip_port):
        try:
            print(f"Проверяем доступность {ip_port}", end='')
            # Выполняем команду psping
            result = subprocess.run(['psping', ip_port], capture_output=True, text=True)
            # Проверяем, есть ли в выводе сообщение об успешном пинге
            if "(0% loss)" in result.stdout:
                print(f"\rПроверяем доступность {ip_port} - доступен")
                return True
            if "(25% loss)" in result.stderr or "50% loss" in result.stdout:
                print(f"\rПроверяем доступность {ip_port} - потери пакетов")
                return True
            if "(100% loss)" in result.stdout:
                print(f"\rПроверяем доступность {ip_port} - недоступен")
                return False
        except Exception as e:
            print(f"Ошибка при проверке {ip_port}: {e}")
        return False
    
    
    # Чтение IP:port из файла и запись доступных в другой файл
    def check_ips_from_file(input_file, output_file):
        with open(input_file, 'r') as infile, open(output_file, 'w') as outfile:
            for line in infile:
                ip_port = line.strip()  # Убираем лишние пробелы и символы новой строки
                if check_ip(ip_port):
                    outfile.write(ip_port + '\n')  # Записываем доступный IP:port в файл
    
    
    # Указываем имена файлов
    input_file = 'ip.txt'
    output_file = 'ipUP.txt'
    
    # Запускаем проверку
    check_ips_from_file(input_file, output_file)
    Ответ написан
  • Как найти паттерн на картинке с OpenCV?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    673e7b80e4dfd963850969.png
    Код:
    spoiler
    import cv2
    import numpy as np
    
    def find_and_draw_template(template_path, original_image_path):
        # Загрузка шаблона
        template = cv2.imread(template_path)
        template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
    
        # Создание объекта ORB
        orb = cv2.ORB_create()
        bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    
        # Обнаружение ключевых точек и вычисление дескрипторов для шаблона
        keypoints_template, descriptors_template = orb.detectAndCompute(template_gray, None)
    
        # Обработка изображения
        image = original_image_path.copy()
        image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
        # Обнаружение ключевых точек и вычисление дескрипторов для изображения
        keypoints_image, descriptors_image = orb.detectAndCompute(image_gray, None)
    
        # Сопоставление дескрипторов
        matches = bf.match(descriptors_template, descriptors_image)
        matches = sorted(matches, key=lambda x: x.distance)
    
        # Отладочная информация
        print(f"Общее количество найденных соответствий: {len(matches)}")
    
        # Отбор лучших соответствий
        good_matches = matches[:75]
        print(f"Количество хороших соответствий: {len(good_matches)}")
    
        # Проверка на наличие хороших соответствий
        if len(good_matches) >= 4:
            # Получение координат ключевых точек
            src_pts = np.float32([keypoints_template[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
            dst_pts = np.float32([keypoints_image[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
    
            # Нахождение матрицы гомографии
            M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
            print("Гомография найдена.")
    
            # Получение углов шаблона
            h, w = template_gray.shape[:2]
            pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
    
            # Преобразование углов шаблона
            dst = cv2.perspectiveTransform(pts, M)
    
            # Обводим рамкой найденные области
            image = cv2.polylines(image, [np.int32(dst)], isClosed=True, color=(0, 255, 0), thickness=3)
        else:
            print("Недостаточно хороших соответствий для нахождения гомографии.")
    
        return image
    
    # Пример использования функции
    template_file = 'LED.jpg'              # Шаблон
    original_image_file = 'outputImage.jpg'  # Исходное изображение
    
    # Загрузка и обработка изображения
    original_image = cv2.imread(original_image_file)
    result_image = find_and_draw_template(template_file, original_image)
    
    # Масштабируем изображение для отображения - не обязательно, у меня не вмещалось в просмотр
    scale_percent = 50  # Процент уменьшения размера
    width = int(result_image.shape[1] * scale_percent / 100)
    height = int(result_image.shape[0] * scale_percent / 100)
    resized_image = cv2.resize(result_image, (width, height), interpolation=cv2.INTER_AREA)
    
    # Отображение результата
    cv2.imshow('Detected Templates', resized_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    Ответ написан
    Комментировать
  • Как получить цвет приложения на котором находится моё приложение?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Код:
    spoiler
    import sys
    from PyQt5 import QtWidgets, QtCore, QtGui
    
    
    class ClockWidget(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
    
            # Устанавливаем параметры окна
            self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint)
            self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
    
            # Устанавливаем таймер для обновления времени
            self.timer = QtCore.QTimer(self)
            self.timer.timeout.connect(self.update_time)
            self.timer.start(1000)  # Обновляем каждую секунду
    
            # Создаем метку для отображения времени
            self.label = QtWidgets.QLabel(self)
            self.label.setAlignment(QtCore.Qt.AlignCenter)
            self.label.setStyleSheet("font-size: 48px;")  # Размер шрифта
    
            # Устанавливаем начальное время
            self.update_time()
    
            # Устанавливаем размер окна
            self.resize(200, 60)
    
            # Переменные для перемещения окна
            self.dragging = False
            self.drag_position = None
    
        def update_time(self):
            current_time = QtCore.QTime.currentTime()
            self.label.setText(current_time.toString("HH:mm:ss"))
            self.check_color_below_widget()
    
        def check_color_below_widget(self):
            # Получаем глобальные координаты нижней границы виджета
            global_pos = self.mapToGlobal(self.rect().bottomLeft())
    
            # Определяем координаты точки на 10 пикселей ниже
            point_below = global_pos + QtCore.QPoint(0, 10)
    
            # Получаем цвет пикселя в этой точке
            screen = QtWidgets.QApplication.primaryScreen()
            pixel_color = screen.grabWindow(0).toImage().pixel(point_below.x(), point_below.y())
            color = QtGui.QColor(pixel_color)
    
            # Выводим значения RGB для отладки
            print(f"Color below widget: R={color.red()}, G={color.green()}, B={color.blue()}")
    
            # Вычисляем яркость цвета
            brightness = (color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000
    
            # Устанавливаем цвет текста в зависимости от яркости
            if brightness < 128:  # Темный фон
                self.label.setStyleSheet("color: white; font-size: 48px;")
            else:  # Светлый фон
                self.label.setStyleSheet("color: black; font-size: 48px;")
    
        def paintEvent(self, event):
            # Рисуем прозрачный фон
            painter = QtGui.QPainter(self)
            painter.setRenderHint(QtGui.QPainter.Antialiasing)
            painter.setBrush(QtGui.QColor(0, 0, 0, 0))
    
        def mousePressEvent(self, event):
            if event.button() == QtCore.Qt.LeftButton:
                self.dragging = True
                self.drag_position = event.globalPos() - self.frameGeometry().topLeft()
    
        def mouseMoveEvent(self, event):
            if self.dragging:
                self.move(event.globalPos() - self.drag_position)
    
        def mouseReleaseEvent(self, event):
            if event.button() == QtCore.Qt.LeftButton:
                self.dragging = False
    
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        clock = ClockWidget()
        clock.show()
        sys.exit(app.exec_())


    673d462f556b5211575721.png
    Ответ написан
    2 комментария
  • Как использовать кириллицу в footer wkhtmltopdf?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    import pdfkit
    import requests
    
    options = {
        "orientation": "portrait",
        "page-size": "A4",
        "margin-top": "1.0cm",
        "margin-right": "1cm",
        "margin-bottom": "1.5cm",
        "margin-left": "1cm",
        "encoding": "utf-8",
    
        'footer-center': "Страница [page] из [toPage]",
        'footer-font-size': 10,
    
    }
    
    url = 'https://pingvinus.ru/note/find-big-files'
    r = requests.get(url)
    pdfkit.from_string(r.text, f'{url.split("/")[-1]}.pdf', options=options, verbose=True)


    Код отрабатывает корректно:

    673bf6d7765f7197952492.png

    Мне кажется, имеет смысл смотреть что у вас в out.
    Ответ написан
  • Что не так с sql запросом?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Использование f-строк для вставки данных в SQL запросы может привести к уязвимостям, связанным с SQL-инъекциями. Вместо использования f-строк, рекомендуется применять параметризованные запросы или подготовленные выражения, что позволяет безопасно передавать данные в запросы.
    Ответ написан
    Комментировать
  • VitHybrid не может добавить позиционные эмбеддинги. Что делать?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    from transformers import ViTHybridConfig, ViTHybridModel
    
    configuration = ViTHybridConfig(patch_size=12)
    model = ViTHybridModel(configuration)
    
    configuration = model.config

    print(configuration.patch_size)
    >>>12
    Ответ написан
    Комментировать
  • Что за способ представления float через 4 byte и int?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    import struct
    
    float_value = 3.50999999
    
    # Преобразуем float в байты
    byte_value = struct.pack('f', float_value)
    
    # Преобразуем байты в целое число
    int_value = int.from_bytes(byte_value, byteorder='little')
    print(int_value)
    Ответ написан
    1 комментарий
  • Не получается спарсить ссылку с Binance?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Ссылки генерируются динамически: в вашем r.text нет искомых ссылок. Без использования браузера под капотом не получится.

    from playwright.sync_api import sync_playwright
    
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto('https://www.binance.com/ru/support/announcement/новые-листинги-криптовалюты?c=48&navId=48&hl=ru')
    
        # Ждем, пока контент загрузится
        page.wait_for_timeout(2000)
    
        # Извлекаем ссылки
        links = page.query_selector_all('a[class="css-1w8j6ia"]')
        for link in links:
            href = link.get_attribute('href')
            if href:
                full_url = f"https://www.binance.com{href}"
                print(full_url)
    
        browser.close()
    Ответ написан
    1 комментарий
  • Как запустить одну и ту же функцию с разными параметрами одновременно?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Использовать multiprocessing?

    from multiprocessing import Process
    
    ...
    if __name__ == '__main__':
        while True:
            processes = []
            processes.append(Process(target=main, args=('https://rust.tm/item/5358808098-0-Shipping%20Container%20Garage%20Door/', 'Shipping Container Garage Door', 60)))
            processes.append(Process(target=main, args=('https://rust.tm/item/5518269987-0-Abyss%20Vest/', 'Abyss Vest', 140)))
            processes.append(Process(target=main, args=('https://rust.tm/item/4136069987-0-Weather%20Large%20Wood%20Box/', 'Weather Large Wood Box', 100)))
    
            for process in processes:
                process.start()
    
            for process in processes:
                process.join()
    
            time.sleep(5)  # Задержка перед следующим циклом
    Ответ написан
    Комментировать
  • Почему парсер не собирает данные и записывает пустые значения?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Есть несколько моментов:
    1. Про длинный кусок кода: он и не будет работать так, как вы хотите, потому что вы передаёте аргумент with_extra_data=True в свою самописную функцию, а в parser.get_flats() - нет. Соответственно он и не парсит дополнительные поля, отсюда и: "пробовала вывести ключи: смотрю, а их там тупо нет".
    Должно быть:
    data = parser.get_flats(deal_type=deal_type, rooms=rooms, with_extra_data=True,  additional_settings={"start_page": page, "end_page": page})


    2. Если вы действительно использовали эти прокси (а не просто привели их для примера), то это бессмысленно - они нерабочие. Прокси из свободного доступа редко долго живут, а тут они вообще из примера на pypi.org / github.

    3. Вёрстка сайтов постоянно изменяется, в том числе и для противодействия парсингу. Текущая версия циана не имеет<span> c текстом "Тип жилья", а именно такой селектор использовался в библиотеке парсера, следовательно он всегда будет отдавать -1 для object_type.

    4. Если вы всё-таки хотите парсить сайт, используя cianparser, то вам нужно внести несколько изменений в файл библиотеки: "Путь до вашего проекта\venv\Lib\site-packages\cianparser\flat\page.py".
    В функцию__parse_flat_offer_page_json__(self)после инициализации словаря page_data, добавить:
    ot = self.offer_page_soup.select_one('[data-name="OfferSummaryInfoItem"] p:nth-of-type(2)').get_text()
    page_data["object_type"] = ot

    и закомментировать строчки:
    # if "Тип жилья" == span.text:
    #     page_data["object_type"] = spans[index + 1].text


    Результат:
    671dbfa43dc32277607933.png
    Ответ написан
    3 комментария
  • Как связать код Python и GUI на wxPython?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    6717cf333e689297739155.png
    Код
    import wx
    
    class MyFrame(wx.Frame):
        def __init__(self, *args, **kwds):
            kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
            wx.Frame.__init__(self, *args, **kwds)
            self.SetSize((250, 250))
            self.SetTitle("frame")
    
            sizer_1 = wx.WrapSizer(wx.VERTICAL)
    
            fields = [
                ("Ширина (м)", "a"),
                ("Длина (м)", "b"),
                ("Высота (м)", "h"),
                ("Окно ширина (м)", "o1"),
                ("Окно высота (м)", "o2"),
                ("Дверь ширина (м)", "d1"),
                ("Дверь высота (м)", "d2"),
            ]
    
            # Create grid sizers and controls dynamically
            for label_text, attr in fields:
                grid_sizer = wx.GridSizer(1, 2, 0, 0)
                sizer_1.Add(grid_sizer, 1, wx.EXPAND, 0)
    
                label = wx.StaticText(self, wx.ID_ANY, label_text)
                grid_sizer.Add(label, 0, wx.ALL, 1)
    
                text_ctrl = wx.TextCtrl(self, wx.ID_ANY, "")
                setattr(self, attr, text_ctrl)  # Store the text control in the instance
                grid_sizer.Add(text_ctrl, 0, 0, 0)
    
            # Create a horizontal sizer for the result and button
            h_sizer = wx.BoxSizer(wx.HORIZONTAL)
    
            # Result text control
            self.itogo = wx.TextCtrl(self, wx.ID_ANY, "")
            self.itogo.SetBackgroundColour((171, 171, 171))
            h_sizer.Add(self.itogo, 1, wx.EXPAND | wx.ALL, 5)
    
            # Calculate button
            self.button_1 = wx.Button(self, wx.ID_ANY, "Посчитать", size=(110, 21))
            h_sizer.Add(self.button_1, 0, wx.ALL, 5)
            self.button_1.Bind(wx.EVT_BUTTON, self.onclick)
    
            # Add the horizontal sizer to the main sizer
            sizer_1.Add(h_sizer, 0, wx.EXPAND, 0)
    
            self.SetSizer(sizer_1)
            self.Layout()
    
        def onclick(self, event):
            a = float(self.a.GetValue())
            b = float(self.b.GetValue())
            h = float(self.h.GetValue())
            o1 = float(self.o1.GetValue())
            o2 = float(self.o2.GetValue())
            d1 = float(self.d1.GetValue())
            d2 = float(self.d2.GetValue())
    
            result = round(a * 2 * h + b * 2 * h - o1 * o2 - d1 * d2, 2)
            self.itogo.SetValue(str(result))
    
    class MyApp(wx.App):
        def OnInit(self):
            self.frame = MyFrame(None, wx.ID_ANY, "")
            self.SetTopWindow(self.frame)
            self.frame.Show()
            return True
    
    
    if __name__ == "__main__":
        app = MyApp(0)
        app.MainLoop()
    Ответ написан
    1 комментарий
  • Почему pypsexec не выводит приложение на экран?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    1. Используйте r перед ф-строкой во избежание нескольких invalid escape sequence:
    command = rf'C:\PsTools\psexec.exe -i 1 -s \\192.168.11.18 -u user -p password calc.exe'

    У меня код с subprocess отрабатывает корректно:
    import subprocess
    
    
    def f():
        command = rf'C:\Portable\Sysinternal\PsExec.exe -i 1 -s \\192.168.0.3 -u user -p password calc.exe'
        return subprocess.call(command, stdout=subprocess.DEVNULL)


    2. Вариант с pypsexec у меня отрабатывает некорректно - GUI запускается, но с артефактами.
    Помимо interactive=True, надо указать номер сессии (можно узнать через cmd -> query user), например: interactive_session=1. Это аналог -i 1 в psexec.

    c.run_executable (executable: "cmd.exe", arguments=r"/c start calc.exe", interactive=True, interactive_session=1)
    Ответ написан
    Комментировать
  • Я учу питон, и в данный момент я пытаюсь сделать калькулятор который проверяет данные которые вводит пользователь?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    С одним циклом:
    num_1 = None
    num_2 = None
    effect = None
    
    while True:
        if num_1 is None:
            input_value = input("Введите первое число: ")
            if input_value.isdigit():
                num_1 = int(input_value)
            else:
                print('Вы ввели не число!')
                continue
    
        if num_2 is None:
            input_value = input("Введите второе число: ")
            if input_value.isdigit():
                num_2 = int(input_value)
            else:
                print('Вы ввели не число!')
                continue
    
        if effect is None:
            input_value = input(
                "Напишите что вы хотите сделать (отнять, прибавить, умножить, разделить, возвести в степень, целое деление, остаток от деления): ")
            if input_value in ("+", "-", "*", "/", "**", "//", "%"):
                effect = input_value
                break
            else:
                print('Нету такого действия!')
                continue
    
    # Выполнение операции
    if effect == "+":
        print(num_1 + num_2)
    elif effect == "-":
        print(num_1 - num_2)
    elif effect == "*":
        print(num_1 * num_2)
    elif effect == "/":
        print(num_1 / num_2)
    elif effect == "**":
        print(num_1 ** num_2)
    elif effect == "//":
        print(num_1 // num_2)
    elif effect == "%":
        print(num_1 % num_2)
    Ответ написан
    Комментировать
  • Переменные на кирилице?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Никак не влияет.
    Нравится, удобно - пишите. Особенно, если не планируете что ваш код будут использовать/поддерживать иностранцы.
    Ответ написан
    3 комментария
  • Почему в данном примере запуска потока с переданным аргументом, есть разница между способом передачи аргумента?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    В любом замыкании в Python переменные связываются по имени.
    l = []
    for i in range(3):
        l.append(lambda: i)
    print([f() for f in l])
    >>> [2, 2, 2]


    Выход из ситуации — создание отдельной функции или передача аргументов по их имени:
    l = []
    for i in range(3):
        l.append(lambda i = i : i)
    print([f() for f in l])
    >>> [0, 1, 2]


    Т.е. это не вопрос в потоках.
    Ответ написан
    Комментировать
  • Как решить проблему с терминалом PyCharm?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    1. Не использовать пробелы в пути.
    2. Или заключить путь c пробелами в двойные кавычки.
    Ответ написан
    Комментировать
  • Почему не находит картинку pyautogui?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Запускать как-нибудь так?
    while True:
        try:
            x = pa.locateCenterOnScreen(r"C:\Python Scripts\library\proga.png", confidence=0.5)
            print(x)
        except Exception as e:
            print(e)

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

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    for i in read:
        print(i['title'])
        user_answer = input('Это нужное объявление? (y/n) ')  # получаем ответ пользователя 
        if user_answer == 'y':
            ...
        else:
            ...
    Ответ написан
  • Почему не работает код?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    Потому что len_pass_numbers.lower() (и прочие) возвращает вам строку 'да', а вы сравниваете с 'Да'.
    Соответственно ваш "алфавит" - chars - пустой.

    Ну и, вероятно, удобнее пользоваться встроенными коллекциями, чем вручную набивать:
    from string import digits, ascii_lowercase, ascii_uppercase, punctuation
    Ответ написан
    3 комментария
  • Не могу получать ответ в авторизации через python?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    У меня работает так:
    1. Авторизация:
    import requests
    
    url = 'https://texttospeech.ru/api/v1/login'
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0',
        'Content-Type': 'text/plain;charset=UTF-8',
    }
    
    data = {"email": "sample@email.com", "pass": "password", "captcha": ""}
    
    session = requests.Session()
    response = session.post(url, json=data)
    
    print(response.text)

    65ee54c4e9c13651933899.png

    2. Код для генерации mp3 из текста:
    import requests
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0',
        'Content-Type': 'text/plain;charset=UTF-8',
    }
    
    
    def get_token() -> str:
        url = 'https://texttospeech.ru/api/v1/login'
        data = {"email": "sample@email.com", "pass": "password", "captcha": ""}
        with requests.Session() as session:
            response = session.post(url, headers=headers, json=data)
            token = response.json().get('data').get('token')
            return token
    
    
    headers['token'] = get_token()
    
    
    def synthesize(text: str) -> None:
        url = 'https://texttospeech.ru/api/v1/synthesize'
        data = {"rate": "0", "pitch": "0", "volume": "0", "hertz": "0", "shift": "0", "echo": "0",
                "text": f'{text}',
                "code": "ru-RU009",
                "format": "mp3"}
        with requests.Session() as session:
            response = session.post(url, headers=headers, json=data)
            if response.status_code == 200:
                print(response.json().get('message'))
                filelink = response.json().get('data').get('filelink')
                with open(f'{text[0:10]}.mp3', 'wb') as file:
                    response = session.get(f'https://texttospeech.ru/{filelink}', headers=headers)
                    file.write(response.content)
            else:
                print(response.text)
    
    
    synthesize('Привет мир')
    Ответ написан