code import sys import time import threading import requests from bs4 import BeautifulSoup from googletrans import Translator from PyQt5.QtCore import Qt, QPropertyAnimation, QSize from PyQt5.QtWidgets import ( QApplication, QMainWindow, QWidget, QPushButton, QTextEdit, QVBoxLayout, QHBoxLayout, QLabel, QSlider, QComboBox, QRadioButton, QButtonGroup, QCheckBox, QStackedWidget ) from PyQt5.QtGui import QIcon sections = { "квартиры": "nieruchomosci/mieszkania/", "дома": "nieruchomosci/dom/", "автомобили": "motoryzacja/samochody/", "работа": "praca/", "электроника": "elektronika/", "услуги": "uslugi/", "мебель": "dom-i-ogrod/meble/", } translator = Translator() class ExpandingWidget(QWidget): def __init__(self, content_widget): super().__init__() self.content = content_widget self.content.setMaximumHeight(0) self.content.setVisible(False) self.anim = QPropertyAnimation(self.content, b"maximumHeight") self.anim.setDuration(300) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.content) self.setLayout(layout) self.expanded = False def toggle(self): if self.expanded: self.anim.setStartValue(self.content.maximumHeight()) self.anim.setEndValue(0) self.anim.start() self.content.setVisible(False) else: self.content.setVisible(True) self.anim.setStartValue(0) self.anim.setEndValue(self.content.sizeHint().height()) self.anim.start() self.expanded = not self.expanded class ParserPage(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.start_btn = QPushButton("Старт") self.stop_btn = QPushButton("Стоп") self.stop_btn.setEnabled(False) buttons = QHBoxLayout() buttons.addWidget(self.start_btn) buttons.addWidget(self.stop_btn) self.log_output = QTextEdit() self.log_output.setReadOnly(True) layout = QVBoxLayout() layout.addLayout(buttons) layout.addWidget(self.log_output) self.setLayout(layout) class SettingsPage(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): layout = QVBoxLayout() layout.setAlignment(Qt.AlignTop) interval_label = QLabel("Интервал парсинга (сек):") self.interval_slider = QSlider(Qt.Horizontal) self.interval_slider.setRange(5, 60) self.interval_slider.setValue(10) self.interval_value_label = QLabel("10 сек") self.interval_slider.valueChanged.connect( lambda val: self.interval_value_label.setText(f"{val} сек") ) layout.addWidget(interval_label) hl = QHBoxLayout() hl.addWidget(self.interval_slider) hl.addWidget(self.interval_value_label) layout.addLayout(hl) layout.addStretch() self.setLayout(layout) class ThemePage(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): layout = QVBoxLayout() layout.setAlignment(Qt.AlignTop) self.radio_light = QRadioButton("Светлая тема") self.radio_dark = QRadioButton("Тёмная тема") self.radio_dark.setChecked(True) self.theme_group = QButtonGroup() self.theme_group.addButton(self.radio_light) self.theme_group.addButton(self.radio_dark) layout.addWidget(self.radio_light) layout.addWidget(self.radio_dark) layout.addStretch() self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Парсер OLX by funtik") self.setWindowIcon(QIcon("icon.png")) self.setGeometry(100, 100, 900, 600) self.menu_widget = QWidget() self.menu_layout = QVBoxLayout() self.menu_widget.setLayout(self.menu_layout) self.btn_parser = QPushButton("Парсер") self.btn_settings = QPushButton("Настройки") self.btn_theme = QPushButton("Тема") for btn in (self.btn_parser, self.btn_settings, self.btn_theme): btn.setCheckable(True) btn.setMinimumHeight(40) btn.setStyleSheet(""" QPushButton { font-size: 16px; text-align: left; padding-left: 10px; } QPushButton:checked { background-color: #448aff; color: white; border-radius: 6px; } """) self.menu_layout.addWidget(self.btn_parser) self.menu_layout.addWidget(self.btn_settings) self.menu_layout.addWidget(self.btn_theme) self.menu_layout.addStretch() self.pages = QStackedWidget() self.page_parser = ParserPage() self.page_settings = SettingsPage() self.page_theme = ThemePage() self.pages.addWidget(self.page_parser) self.pages.addWidget(self.page_settings) self.pages.addWidget(self.page_theme) central_widget = QWidget() main_layout = QHBoxLayout() main_layout.addWidget(self.menu_widget) main_layout.addWidget(self.pages) central_widget.setLayout(main_layout) self.setCentralWidget(central_widget) self.btn_parser.setChecked(True) self.pages.setCurrentWidget(self.page_parser) self.btn_parser.clicked.connect(lambda: self.switch_page(self.btn_parser, self.page_parser)) self.btn_settings.clicked.connect(lambda: self.switch_page(self.btn_settings, self.page_settings)) self.btn_theme.clicked.connect(lambda: self.switch_page(self.btn_theme, self.page_theme)) self.page_parser.start_btn.clicked.connect(self.start_parser) self.page_parser.stop_btn.clicked.connect(self.stop_parser) self.parser_thread = None self.parser_running = False self.current_theme = "dark" self.apply_theme(self.current_theme) self.page_theme.radio_light.toggled.connect(self.on_theme_changed) def switch_page(self, btn, page): for button in (self.btn_parser, self.btn_settings, self.btn_theme): if button != btn: button.setChecked(False) btn.setChecked(True) self.pages.setCurrentWidget(page) def start_parser(self): interval = self.page_settings.interval_slider.value() self.parser_running = True self.page_parser.log_output.append(" Парсер запущен") self.page_parser.start_btn.setEnabled(False) self.page_parser.stop_btn.setEnabled(True) self.parser_thread = threading.Thread(target=self.run_parser, args=(interval,)) self.parser_thread.start() def stop_parser(self): self.parser_running = False self.page_parser.log_output.append(" Парсер остановлен") self.page_parser.start_btn.setEnabled(True) self.page_parser.stop_btn.setEnabled(False) def run_parser(self, interval): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/124.0.0.0 Safari/537.36", "Accept-Language": "pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7", } page = 1 while self.parser_running: try: url = f"https://www.olx.pl/?page={page}" self.page_parser.log_output.append(f"\n Страница {page}: {url}") response = requests.get(url, headers=headers) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") cards = soup.find_all("div", class_="css-1sw7q4x") if not cards: self.page_parser.log_output.append("Больше объявлений не найдено.") break self.page_parser.log_output.append(f"Найдено объявлений: {len(cards)}. Выводим первые 3:") for card in cards[:3]: title = card.find("h6") title_text = title.get_text(strip=True) if title else "Без названия" price = card.find("p", class_="css-10b0gli") price_text = price.get_text(strip=True) if price else "Без цены" location = card.find("span", class_="css-17ctwpz") location_text = location.get_text(strip=True) if location else "Без локации" date_update = card.find("span", class_="css-9s5bis") date_text = date_update.get_text(strip=True) if date_update else "Дата не указана" link_tag = card.find("a", href=True) full_link = "https://www.olx.pl" + link_tag['href'] if link_tag else "Ссылка отсутствует" try: translated_title = translator.translate(title_text, dest='ru').text except Exception: translated_title = title_text self.page_parser.log_output.append( f"Название (оригинал): {title_text}\n" f"Название (перевод): {translated_title}\n" f"Цена: {price_text}\n" f"Локация: {location_text}\n" f"Дата обновления: {date_text}\n" f"Ссылка: {full_link}\n---" ) page += 1 time.sleep(interval) except Exception as e: self.page_parser.log_output.append(f" Ошибка: {e}. Пауза 60 сек...") time.sleep(60) def apply_theme(self, theme): if theme == "dark": self.setStyleSheet(dark_style) self.current_theme = "dark" self.page_theme.radio_dark.setChecked(True) else: self.setStyleSheet(light_style) self.current_theme = "light" self.page_theme.radio_light.setChecked(True) def on_theme_changed(self, checked): if checked: self.apply_theme("light") else: self.apply_theme("dark") dark_style = """ QMainWindow { background-color: #263238; color: #ECEFF1; font-family: Segoe UI; font-size: 14px; } QTextEdit { background-color: #37474F; color: #ECEFF1; border: 1px solid #455A64; } QPushButton { background-color: #546E7A; color: #FFFFFF; border: none; padding: 8px 16px; border-radius: 4px; } QPushButton:hover { background-color: #607D8B; } QPushButton:disabled { background-color: #37474F; color: #B0BEC5; } QSlider::groove:horizontal { height: 8px; background: #455A64; border-radius: 4px; } QSlider::handle:horizontal { background: #90caf9; border-radius: 8px; width: 18px; margin: -5px 0; } QComboBox, QCheckBox { background-color: #546E7A; color: #ECEFF1; border-radius: 4px; padding: 4px; } QLabel, QRadioButton { color: #ECEFF1; } """ light_style = """ QMainWindow { background: #FAFAFA; color: #212121; font-family: Segoe UI; font-size: 14px; } QTextEdit { background-color: #FFFFFF; color: #000000; border: 1px solid #B0BEC5; } QPushButton { background-color: #E0F2F1; color: #004D40; padding: 8px 16px; border: 1px solid #B2DFDB; border-radius: 4px; } QPushButton:hover { background-color: #B2DFDB; } QPushButton:disabled { background-color: #CFD8DC; color: #90A4AE; } QSlider::groove:horizontal { height: 8px; background: #B0BEC5; border-radius: 4px; } QSlider::handle:horizontal { background: #004D40; border-radius: 8px; width: 18px; margin: -5px 0; } QComboBox, QCheckBox { background-color: #E0F2F1; color: #004D40; border-radius: 4px; padding: 4px; } QLabel, QRadioButton { color: #212121; } """ if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) Как можно исправить и какой функционал можно добавить? за код пардон не вставляется нормально