首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Pyinstaller复制窗口构建的PyQT应用程序

用Pyinstaller复制窗口构建的PyQT应用程序
EN

Stack Overflow用户
提问于 2022-09-10 19:03:00
回答 1查看 110关注 0票数 1

我需要在windows上构建可执行文件,但我使用的是ubuntu。我非常担心在linux上构建.exe的可能性。在wine中无法做到这一点,因为包含包有问题,现在我正尝试使用windows 10 on virtual box来完成这个任务。

我用QtDesigner为我的应用程序构建了用户界面。在场景后面,它使用undetected-chromedriverwebdriver-manager下载webdriver驱动程序。App只有一个按钮。

我在linux上建立了测试应用程序,一切都很好。当我在虚拟框的窗口上构建它时,点击按钮,应用程序窗口崩溃了,但没有关闭,opening second window of app和什么都不做。

项目文件夹包含2个文件:app.pyscrap.py

pyinstaller日志:

代码语言:javascript
复制
E:\Programming\10.Review_scrapper>venv\Scripts\python.exe venv\Lib\site-packages\PyInstaller --onefile --windowed --paths venv\Lib\site-packages app.py
619 INFO: PyInstaller: 5.4
624 INFO: Python: 3.10.6
647 INFO: Platform: Windows-10-10.0.19044-SP0
647 INFO: wrote E:\Programming\10.Review_scrapper\app.spec
647 INFO: UPX is not available.
662 INFO: Extending PYTHONPATH with paths
['E:\\Programming\\10.Review_scrapper',
 'E:\\Programming\\10.Review_scrapper\\venv\\Lib\\site-packages']
1406 INFO: checking Analysis
1406 INFO: Building Analysis because Analysis-00.toc is non existent
1406 INFO: Initializing module dependency graph...
1422 INFO: Caching module graph hooks...
1442 INFO: Analyzing base_library.zip ...
4171 INFO: Loading module hook 'hook-heapq.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
4828 INFO: Loading module hook 'hook-encodings.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
7234 INFO: Loading module hook 'hook-pickle.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
9987 INFO: Caching module dependency graph...
10502 INFO: running Analysis Analysis-00.toc
10530 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable
  required by C:\Users\Kutso\AppData\Local\Programs\Python\Python310\python.exe
10657 INFO: Analyzing E:\Programming\10.Review_scrapper\app.py
10984 INFO: Loading module hook 'hook-selenium.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
12015 INFO: Loading module hook 'hook-certifi.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
12312 INFO: Processing pre-safe import module hook urllib3.packages.six.moves from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\pre_safe_import_module\\hook-urllib3.packages.six.moves.py'.
14062 INFO: Loading module hook 'hook-platform.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
14578 INFO: Loading module hook 'hook-xml.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
14578 INFO: Loading module hook 'hook-xml.dom.domreg.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
16189 INFO: Loading module hook 'hook-websockets.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\stdhooks'...
17266 INFO: Processing pre-find module path hook distutils from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\pre_find_module_path\\hook-distutils.py'.
17937 INFO: Loading module hook 'hook-distutils.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
18455 INFO: Loading module hook 'hook-multiprocessing.util.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
20625 INFO: Loading module hook 'hook-PyQt5.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
20921 INFO: Processing module hooks...
21374 INFO: Loading module hook 'hook-setuptools.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
26281 INFO: Loading module hook 'hook-distutils.util.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
26328 INFO: Loading module hook 'hook-sysconfig.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
26749 INFO: Loading module hook 'hook-pkg_resources.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
30375 INFO: Processing pre-safe import module hook win32com from 'E:\\Programming\\10.Review_scrapper\\venv\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\hooks\\pre_safe_import_module\\hook-win32com.py'.
32297 WARNING: Hidden import "sip" not found!
32297 INFO: Loading module hook 'hook-PyQt5.QtCore.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
32547 INFO: Loading module hook 'hook-PyQt5.QtGui.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
33281 INFO: Loading module hook 'hook-PyQt5.QtWidgets.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
34376 INFO: Processing pre-find module path hook site from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\pre_find_module_path\\hook-site.py'.
34376 INFO: site: retargeting to fake-dir 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\fake-modules'
34534 INFO: Loading module hook 'hook-setuptools.msvc.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
36234 INFO: Loading module hook 'hook-difflib.py' from 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks'...
37699 INFO: Looking for ctypes DLLs
37791 INFO: Analyzing run-time hooks ...
37837 INFO: Including run-time hook 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py'
37837 INFO: Including run-time hook 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_subprocess.py'
37854 INFO: Including run-time hook 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pyqt5.py'
37854 INFO: Including run-time hook 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py'
37854 INFO: Including run-time hook 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_multiprocessing.py'
37854 INFO: Including run-time hook 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_setuptools.py'
37854 INFO: Including run-time hook 'E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgres.py'
37931 INFO: Looking for dynamic libraries
1156 INFO: Extra DLL search directories (AddDllDirectory): ['E:\\Programming\\10.Review_scrapper\\venv\\Lib\\site-packages\\PyQt5\\Qt5\\bin']
1156 INFO: Extra DLL search directories (PATH): ['E:\\Programming\\10.Review_scrapper\\venv\\Lib\\site-packages\\PyQt5\\Qt5\\bin', 'C:\\Windows\\system32', 'C:\\Windows', 'C:\\Windows\\System32\\Wbem', 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\', 'C:\\Windows\\System32\\OpenSSH\\', 'C:\\Users\\Kutso\\AppData\\Local\\Programs\\Python\\Python310\\Scripts\\', 'C:\\Users\\Kutso\\AppData\\Local\\Programs\\Python\\Python310\\', 'C:\\Users\\Kutso\\AppData\\Local\\Microsoft\\WindowsApps']
41682 INFO: Looking for eggs
41682 INFO: Using Python library C:\Users\Kutso\AppData\Local\Programs\Python\Python310\python310.dll
41682 INFO: Found binding redirects:
[]
41698 INFO: Warnings written to E:\Programming\10.Review_scrapper\build\app\warn-app.txt
41931 INFO: Graph cross-reference written to E:\Programming\10.Review_scrapper\build\app\xref-app.html
41995 INFO: checking PYZ
42014 INFO: Building PYZ because PYZ-00.toc is non existent
42014 INFO: Building PYZ (ZlibArchive) E:\Programming\10.Review_scrapper\build\app\PYZ-00.pyz
43947 INFO: Building PYZ (ZlibArchive) E:\Programming\10.Review_scrapper\build\app\PYZ-00.pyz completed successfully.
43994 INFO: checking PKG
43994 INFO: Building PKG because PKG-00.toc is non existent
43994 INFO: Building PKG (CArchive) app.pkg
56229 INFO: Building PKG (CArchive) app.pkg completed successfully.
56249 INFO: Bootloader E:\Programming\10.Review_scrapper\venv\lib\site-packages\PyInstaller\bootloader\Windows-64bit\runw.exe
56249 INFO: checking EXE
56261 INFO: Building EXE because EXE-00.toc is non existent
56261 INFO: Building EXE from EXE-00.toc
56261 INFO: Copying bootloader EXE to E:\Programming\10.Review_scrapper\dist\app.exe.notanexecutable
56388 INFO: Copying icon to EXE
56388 INFO: Copying icons from ['E:\\Programming\\10.Review_scrapper\\venv\\lib\\site-packages\\PyInstaller\\bootloader\\images\\icon-windowed.ico']
56520 INFO: Writing RT_GROUP_ICON 0 resource with 104 bytes
56520 INFO: Writing RT_ICON 1 resource with 3752 bytes
56520 INFO: Writing RT_ICON 2 resource with 2216 bytes
56529 INFO: Writing RT_ICON 3 resource with 1384 bytes
56529 INFO: Writing RT_ICON 4 resource with 38188 bytes
56529 INFO: Writing RT_ICON 5 resource with 9640 bytes
56529 INFO: Writing RT_ICON 6 resource with 4264 bytes
56529 INFO: Writing RT_ICON 7 resource with 1128 bytes
56529 INFO: Copying 0 resources to EXE
56529 INFO: Embedding manifest in EXE
56529 INFO: Updating manifest in E:\Programming\10.Review_scrapper\dist\app.exe.notanexecutable
56700 INFO: Updating resource type 24 name 1 language 0
56700 INFO: Appending PKG archive to EXE
56791 INFO: Fixing EXE headers
58264 INFO: Building EXE from EXE-00.toc completed successfully

app.py:

代码语言:javascript
复制
import time
from scrap import Scrapper
from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(420, 327)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.formLayout = QtWidgets.QFormLayout()
        self.formLayout.setObjectName("formLayout")
        self.input_url = QtWidgets.QLineEdit(self.centralwidget)
        self.input_url.setObjectName("input_url")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.input_url)
        self.verticalLayout.addLayout(self.formLayout)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.button_collect_data = QtWidgets.QPushButton(self.centralwidget)
        self.button_collect_data.setMaximumSize(QtCore.QSize(399, 16777215))
        self.button_collect_data.setObjectName("button_collect_data")
        self.horizontalLayout.addWidget(self.button_collect_data)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.formLayout_2 = QtWidgets.QFormLayout()
        self.formLayout_2.setObjectName("formLayout_2")
        self.console = QtWidgets.QTextEdit(self.centralwidget)
        self.console.setReadOnly(True)
        self.console.setObjectName("console")
        self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.console)
        self.verticalLayout.addLayout(self.formLayout_2)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
        self.add_functions()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.input_url.setText(_translate("MainWindow", "Введите URL"))
        self.button_collect_data.setText(_translate("MainWindow", "Пуск"))

    def add_functions(self):
        self.button_collect_data.clicked.connect(lambda: self.run_collect_data())

    def run_collect_data(self):
        self.console.clear()
        self.console.append('Скрипт запущен...')
        url = self.get_url()
        Scrapper().scrap_page(url)
        self.console.append('Выполнение скрипта завершено')

    def get_url(self):
        text = self.input_url.text()
        return text

    def normalOutputWritten(self, text):
        """Append text to the QTextEdit."""
        # Maybe QTextEdit.append() works as well, but this is how I do it:
        cursor = self.console.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.console.setTextCursor(cursor)
        self.console.ensureCursorVisible()


class EmittingStream(QtCore.QObject):
    textWritten = QtCore.pyqtSignal(str)

    def write(self, text):
        self.textWritten.emit(str(text))


class InvalidUrl(BaseException):
    pass


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

scrap.py:

代码语言:javascript
复制
import json
import csv
import os.path
import re
import traceback
from time import sleep

import undetected_chromedriver.v2 as uc
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager


def create_txt(filepath='output.txt'):
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write('Программа обработки отзывов\n')


def append_dict_to_txt(reviews_info: dict, filepath='output.txt'):
    url = list(reviews_info.keys())[0]
    with open(filepath, 'a', encoding='utf-8') as f:
        f.write(f'url:\n{url}\n')
        for i, d in reviews_info[url].items():
            f.write(f'id: {i}\n')
            for k, v in d.items():
                if k in ('positive', 'negative'):
                    f.write(f'type: {k}\nreview: {v}\n')
                else:
                    f.write(f'{k}: {v}\n')


class Scrapper:
    def __init__(self):
        self.driver = None
        self.page_load_time_out = 20

    def get_driver(self):
        # options = webdriver.ChromeOptions()
        options = uc.ChromeOptions()
        # fake user agent
        options.add_argument(
            f'user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
        )
        # headless mode
        options.headless = True
        # maximized window
        options.add_argument('--start-maximized')
        options.add_argument('--disable-notifications')
        driver = uc.Chrome(
            options=options,
            version_main=104,
            service=Service(ChromeDriverManager().install())
        )
        self.driver = driver

    def get_page_with_retries(self, url, retries_get_page=3):
        i = 0
        while True:
            i += 1
            self.get_driver()
            self.driver.set_page_load_timeout(self.page_load_time_out)
            try:
                print(f'Страница загружается... {url=}')
                self.driver.get(url)
                break
            except TimeoutException:
                if retries_get_page == i:
                    print(f'Страница не загрузилась после {i} попыток')
                    return
                else:
                    print(f'Страница не загрузилась с таймаутом {self.page_load_time_out}.'
                          f' Попыток осталось: {retries_get_page - i}')
                    self.driver.quit()

    def open_google_translate_tab(self):
        og_tab = self.driver.current_window_handle
        assert len(self.driver.window_handles) == 1
        self.driver.switch_to.new_window('tab')
        url = 'https://translate.google.com/?sl=auto&tl=ru'
        print(f'Открываем переводчик')
        self.driver.get(url)
        WebDriverWait(self.driver, 10).until(
            EC.number_of_windows_to_be(2)
        )
        sleep(1)
        print(f'Переводчик открылся')
        self.driver.switch_to.window(og_tab)

    def translate_to_ru(self, text):
        try:
            og_tab = self.driver.current_window_handle
            assert len(self.driver.window_handles) == 2
            translate_tab = self.driver.window_handles[1]
            self.driver.switch_to.window(translate_tab)
            text_input = self.driver.find_element(By.XPATH, '//textarea[@aria-label="Исходный текст"]')
            text_input.clear()
            sleep(1)
            # text_input.send_keys(text)
            js_add_text_to_input = """
              var elm = arguments[0], txt = arguments[1];
              elm.value += txt;
              elm.dispatchEvent(new Event('change'));
            """
            self.driver.execute_script(js_add_text_to_input, text_input, text)
            text_input.send_keys(' ')
            sleep(1)
            text_output = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.XPATH, '//span[@lang="ru"]/span/span'))
            ).text
            # self.driver.find_element(By.XPATH, '//span[@lang="ru"]/span/span').text
            self.driver.switch_to.window(og_tab)
            print(f'Текст: "{text}" переведен как: "{text_output}"')
            return text_output
        except:
            return None

    def scrap_page(self, url, filepath='output.txt'):
        try:
            create_txt(filepath)
            self.get_page_with_retries(url, 3)
            self.open_google_translate_tab()

            # accept cookies
            try:
                self.driver.find_element(By.XPATH, '//button[@id="onetrust-accept-btn-handler"]').click()
                sleep(1)
            except NoSuchElementException:
                pass

            self.driver.find_element(By.XPATH, '//div[@class="hp-featured_reviews-bottom"]/button').click()
            reviews_info = {url: {}}
            while True:
                # wait until loading finished
                while True:
                    try:
                        self.driver.find_element(
                            By.XPATH, '//div[@id="review_list_page_container"][@style="display: block;"]'
                        )
                        break
                    except NoSuchElementException:
                        continue
                sleep(1)

                divs_reviews = self.driver.find_elements(
                    By.XPATH, '//div[@class="c-review-block"]'
                )
                for div_review in divs_reviews:
                    nickname, date, review_title, review_info = None, None, None, None
                    positive, negative = '', ''
                    translated, translate_error = False, False
                    ActionChains(self.driver).scroll_to_element(div_review).perform()

                    # Press translate button if it exists
                    try:
                        div_review.find_element(
                            By.XPATH, './/a[text()="Показать перевод"]'
                        ).click()
                        while translated is False and translate_error is False:
                            try:
                                div_review.find_element(
                                    By.XPATH, './/span[@style="display: inline;"]/'
                                              'span[normalize-space(text())="Переведено"]'
                                )
                                translated = True
                            except NoSuchElementException:
                                pass
                            try:
                                div_review.find_element(
                                    By.XPATH, './/span[@style="display: inline;"][contains(text(), "Не удалось перевести")]'
                                )
                                translate_error = True
                            except NoSuchElementException:
                                pass
                    except NoSuchElementException:
                        pass

                    nickname = div_review.find_element(
                        By.CLASS_NAME, 'bui-avatar-block__title'
                    ).text
                    date = div_review.find_element(
                        By.XPATH, './/div[@class="c-review-block__row"]/span[@class="c-review-block__date"]'
                    ).text.replace('Время отзыва: ', '')

                    if not translate_error:
                        positives = div_review.find_elements(
                            By.XPATH, './/span[text()="Понравилось"]/parent::span/following-sibling::'
                                      'span[contains(@class, "c-review__body")]'
                        )
                    else:
                        positives = div_review.find_elements(
                            By.XPATH, './/span[@class="c-review__prefix c-review__prefix--color-green"]'
                                      '/following-sibling::span[@lang]'
                        )
                    match positives:
                        case []:
                            positive = ''
                        case [arg]:
                            positive = arg.text
                        case [*args]:
                            positive = [p for p in args if p.get_attribute('style') == 'display: inline;'][0].text
                    if positive:
                        if translate_error or not re.search(r'[А-я]', positive):
                            positive = self.translate_to_ru(positive)

                    if not translate_error:
                        negatives = div_review.find_elements(
                            By.XPATH, './/span[text()="Не понравилось"]/parent::span'
                                      '/following-sibling::span[contains(@class, "c-review__body")]'
                        )
                    else:
                        negatives = div_review.find_elements(
                            By.XPATH, './/span[@class="c-review__prefix"]/following-sibling::span[@lang]'
                        )
                    match negatives:
                        case []:
                            negative = ''
                        case [arg]:
                            negative = arg.text
                        case [*args]:
                            negative = [p for p in args if p.get_attribute('style') == 'display: inline;'][0].text
                    if negative:
                        if translate_error or not re.search(r'[А-я]', negative):
                            negative = self.translate_to_ru(negative)

                    review_info = {
                        'author': nickname,
                        'date': date,
                        'positive': positive,
                        'negative': negative
                    }

                    if negative or positive:
                        reviews_info[url][len(reviews_info[url]) + 1] = review_info
                        print(len(reviews_info[url]), review_info)
                    else:
                        print('В отзыве отсутствуют негативные или положительные комментарии')

                try:
                    self.driver.find_element(By.XPATH, '//a[@class="pagenext"]').click()
                except NoSuchElementException:
                    break

            append_dict_to_txt(reviews_info, filepath)
            # with open('reviews_example.json', 'w') as f:
            #     json.dump(reviews_info, f, indent=4, ensure_ascii=False)

            # columns = ('url', 'id', 'author', 'date', 'positive', 'negative')
            # with open('reviews_example.csv', 'a', encoding='utf-8') as f:
            #     writer = csv.writer(f, delimiter=';')
            #     writer.writerow(columns)
            #     for i, d in reviews_info[url].items():
            #         if i == 1:
            #             row_data = [url, i]
            #         else:
            #             row_data = [None, i]
            #         for column in columns[2:]:
            #             if v := d.get(column):
            #                 row_data.append(v)
            #             else:
            #                 row_data.append(None)
            #         writer.writerow(row_data)
        except:
            print(traceback.format_exc())
        finally:
            self.driver.quit()


def main():
    # Scrapper().scrap_page('https://www.booking.com/hotel/it/residenza-gonfalone.ru.html?label=gen173nr-1DCAEoggI46AdIM1gEaMIBiAEBmAEhuAEZyAEM2AED6AEBiAIBqAIDuALty5KYBsACAdICJDQwZWM2YmZhLTU5NDItNDgxMi05M2I5LTUyMmExNjhhNDBjZNgCBOACAQ&sid=74e702f2aee6c0eeab7fc4bc642824cd&aid=304142&ucfs=1&arphpl=1&dest_id=-126693&dest_type=city&group_adults=2&req_adults=2&no_rooms=1&group_children=0&req_children=0&hpos=4&hapos=4&sr_order=popularity&srpvid=5c0666a902dd010a&srepoch=1661956563&from=searchresults#hotelTmpl')
    pass


if __name__ == '__main__':
    main()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-13 19:33:00

这可以通过调用多处理模块中的freeze_support()函数来解决。

例如,在app.py文件中:

代码语言:javascript
复制
import time
from multiprocessing import freeze_support   # <---add this
from scrap import Scrapper
from PyQt5 import QtCore, QtGui, QtWidgets

...
...

if __name__ == "__main__":
    import sys
    freeze_support()  # <----- add this
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

此函数只对windows OS有影响,因此在为其他操作系统编译时不需要担心禁用它,而且在使用标准解释器运行时也不应该有任何效果,也不应该将其编译为exe。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73674500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档