In Pycharm venv, I have created a gui with pyinstaller, which calls scrapy on a file with Popen. From terminal Popen was calling scrapy and scraping was being done successfully. After packing gui was being opened but stderr of Popen was telling scrapy not found. A issue I opened on Githubissue helped me to find out that pyinstallerwas using the user package instead of venv. I solved it by installing scrapy for the user and after packing with pyinstaller the built gui is calling scrapy. Still don't know why pyinstaller didn't use venv package.
But now I am getting scrapy error
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/twisted/internet/defer.py", line 62, in run
return f(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/scrapy/core/downloader/middleware.py", line 49, in process_request
return (yield download_func(request=request, spider=spider))
twisted.web._newclient.RequestGenerationFailed: [<twisted.python.failure.Failure builtins.AttributeError: __enter__>]
Even if I run scrapy as user (outside venv), in terminal I get this error. Inside venv running in terminal things are fine.
Also is it the ideal way to pack from pyinstaller i.e. installing packages in user as well, so that pyinstaller can get them?
Gui code
import tkinter as tk
from tkinter import messagebox as tkms
from tkinter import ttk
import shlex
from subprocess import Popen
import json
def get_url():
#printing Entry url to a file
harvest = None
def watch():
global harvest
if harvest:
if harvest.poll() != None:
# Update your progressbar to finished.
progress_bar.stop()
#if harvest finishes OK then show confirmation message otherwise show error.
if harvest.returncode == 0:
mes = tkms.showinfo(title='progress', message='Scraping Done')
if mes == 'ok':
root.destroy()
else:
tkms.showinfo(title='Error', message=f'harvest returncode == {harvest.returncode}')
harvest = None
else:
# indicate that process is running.
progress_bar.grid()
progress_bar.start(10)
root.after(100, watch)
def scrape():
global harvest
command_line = shlex.split('scrapy runspider ./scrape.py')
with open ('stdout.txt', 'wb') as out, open('stderr', 'wb') as err:
harvest = Popen(command_line, stdout=out, stderr=err)
watch()
root = tk.Tk()
root.title("Title")
url = tk.StringVar(root)
entry1 = tk.Entry(root, width=90, textvariable=url)
entry1.grid(row=0, column=0, columnspan=3)
my_button = tk.Button(root, text="Process", command=lambda: [get_url(), scrape()])
my_button.grid(row=2, column=2)
progress_bar = ttk.Progressbar(root, orient=tk.HORIZONTAL, length=300, mode='indeterminate')
progress_bar.grid(row=3, column=2)
progress_bar.grid_forget()
root.mainloop()
Scrapy reproducable code
import scrapy
import json
class ImgSpider(scrapy.Spider):
name = 'img'
#allowed_domains = [user_domain]
start_urls = ['xyz']
def parse(self, response):
title = response.css('img::attr(alt)').getall()
links = response.css('img::attr(src)').getall()
with open('../images/urls.txt', 'w') as f:
for i in title:
f.write(i)
f.close