Reputation: 404
I need to build executable file on windows, but i'm using ubuntu
. I red a lot about possibility of building .exe
on linux. Couldn't do this with wine
because had problems with including packages, and now i'm trying to do this using windows 10 on virtual box
.
I built user interface for my app with QtDesigner
. Behind the scene it's using undetected-chromedriver
, webdriver-manager
to download webdriver. App has just one button.
I built app to test on linux and everything works fine. When i build it on virtual box's windows, click the button, app window is crashing, but not closing, opening second window of app
and doing nothing.
Project folder contains 2 files: app.py
and scrap.py
pyinstaller log:
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 :
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 :
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()
Upvotes: 0
Views: 720
Reputation: 17291
This can be solved by calling the freeze_support()
function in the multiprocessing module.
For example in your app.py
file:
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_())
This function only has an effect on windows OS, so you shouldn't need to worry about disabling it when compiling for other OS's and it also shouldn't have any effect when running with a standard interpreter and not compiled to exe.
Upvotes: 2