如何用PyInstaller将Scrapy项目GUI打包为exe文件?
问题描述
我想把为Scrapy项目开发的GUI程序用PyInstaller打包成exe文件,之前从没使用过该工具。已在Scrapy虚拟环境(venv)中安装PyInstaller并尝试打包,但生成的exe运行时控制台闪退,无法查看错误信息。搜索网络及Stack Overflow的解决方案后仍未匹配到自身问题,现将相关代码附上:
Spider代码
import scrapy import pandas as pd from twisted.internet.error import DNSLookupError class CheckSpider(scrapy.Spider): name = 'check' def read_xl(df): df = pd.read_excel('url.xlsx') return df['url'].tolist() def start_requests(self): for value in self.read_xl(): yield scrapy.Request( url=value, callback= self.parse, errback=self.parse_error ) return super().start_requests() def parse_error(self, failure): if failure.check(DNSLookupError): request = failure.request yield { 'URL': request.url, 'Status': failure.value } def parse(self, response): if response.request.meta.get('redirect_urls'): yield { 'URL': response.request.meta.get('redirect_urls')[0], 'Redireted URL': response.request.url, 'Status': response.status } else: yield { 'URL': response.url, 'Redireted URL': response.request.url, 'Status': response.status }
GUI代码
from tkinter import * from tkinter import messagebox from tkinter import filedialog from scrapy.utils import project from scrapy import spiderloader from scrapy.utils.log import configure_logging from scrapy.crawler import CrawlerRunner from twisted.internet import reactor import threading def get_spiders(): settings = project.get_project_settings() spider_loader = spiderloader.SpiderLoader.from_settings(settings) return spider_loader.list() def browse_button(): global folder_path folder_path = filedialog.askdirectory() folder_path_entry.delete(0, END) folder_path_entry.insert(0, folder_path) return folder_path def execute_spider(): chosen_spider = spider_text.get() chosen_feed = feed_text.get() if dataset_entry.get() == '' or chosen_feed not in ['csv', 'json']: messagebox.showerror('Error', 'All entries are required') return try: feed_uri = f'file:///{folder_path}/{dataset_entry.get()}.{chosen_feed}' except: messagebox.showerror('Error', 'All entries are required') settings = project.get_project_settings() # settings.set('FEED_URI', feed_uri) # settings.set('FEED_TYPE', chosen_feed) settings.set("FEEDS", { f'output.{chosen_feed}': { 'format': chosen_feed, 'encoding': 'utf8' } }) configure_logging() runner = CrawlerRunner(settings) runner.crawl(chosen_spider) reactor.run(installSignalHandlers=False) def start_execute_thread(event): global execute_thread execute_thread = threading.Thread(target=execute_spider, daemon=True) execute_thread.start() app.after(10, check_execute_thread) def check_execute_thread(): if execute_thread.is_alive(): app.after(10, check_execute_thread) app = Tk() # app title app.title('Check Website Status') # app size app.geometry('300x200') app.resizable(False, False) # app label spider_label = Label(app, text='Choose a spider') spider_label.grid(row=0, column=0, sticky=W, pady=10, padx=10) # Choose Spider spider_text = StringVar(app) spider_text.set('Choose a spider') spiders = [spider for spider in get_spiders()] spiders_dropdown = OptionMenu(app, spider_text, *spiders) spiders_dropdown.grid(row=0, column=1, columnspan=2) # Feed Type feed_label = Label(app, text='Choose a feed') feed_label.grid(row=1, column=0, sticky=W, pady=10, padx=10) feed_text = StringVar(app) feed_text.set('Choose a feed') feeds = ['csv', 'json'] feed_dropdown = OptionMenu(app, feed_text, *feeds) feed_dropdown.grid(row=1, column=1, columnspan=2) # path entry folder_path_text = StringVar(app) folder_path_entry = Entry(app, textvariable=folder_path_text) folder_path_entry.grid(row=2, column=0, pady=10, padx=10) # Dataset entry dataset_text = StringVar(app) dataset_entry = Entry(app, textvariable=dataset_text, width=10) dataset_entry.grid(row=2, column=1, pady=10, padx=10) browse_btn = Button(app, text='Browse', command=browse_button) browse_btn.grid(row=2, column=2,) execute_btn = Button(app,text='Execute', command=lambda: start_execute_thread(None)) execute_btn.grid(row=3, column=0, columnspan=3) app.mainloop()
注:此前我曾因该脚本的GUI相关问题向@Alexander求助过。
内容的提问来源于stack exchange,提问作者Raisul Islam
相关产品推荐
相关产品推荐

