#python #sqlite #flask #scrapy
#python #базы данных SQLite #flask #шершавый
Вопрос:
Извините за длинный пост. Как я упоминал в названии, у меня есть веб-приложение flask, которое принимает URL-адрес и отправляет его scrapy spider. Затем spider просматривает ответ и очищает src всех найденных изображений.
Код Spider:
class ContentspiderSpider(scrapy.Spider):
name = 'content'
myBaseUrl = ''
start_urls = []
def __init__(self, category='', **kwargs): #The category variable will have the input URL.
self.myBaseUrl = category
self.start_urls.append(self.myBaseUrl)
super().__init__(**kwargs)
def parse(self, response):
item = WebItem()
images = response.css('img')
for img in images:
src = img.css('img::attr(src)').get()
item['src'] = src
yield item
Очищенные элементы возвращаются в виде файла json. Это код flask, в котором это происходит:
app = Flask(__name__)
output_data = []
crawl_runner = CrawlerRunner()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/', methods=['POST'])
def submit():
if request.method == 'POST':
s = request.form['url']
global baseURL
baseURL = s
return redirect(url_for('scrape'))
@app.route('/scrape')
def scrape():
scrape_with_crochet(baseURL=baseURL) #passing the URL to the scraping function
time.sleep(20)
return jsonify(output_data)
@crochet.run_in_reactor
def scrape_with_crochet(baseURL):
# This will connect to the dispatcher that will kind of loop the code between these two functions.
dispatcher.connect(_crawl_result, signal=signals.item_scraped)
# This will connect to the ReviewspiderSpider function in our scrapy file and after each yield will pass to the crawler_result function.
eventual = crawl_runner.crawl(ContentspiderSpider, category = baseURL)
return eventual
#this will append the data to the output data list
def _crawl_result(item, response, spider):
output_data.append(dict(item))
if __name__ == "__main__":
app.run(debug=True)
Однако я ожидаю, что элементы также будут сохранены в файле db. Поскольку я написал это в конвейере scrapy:
class WebappScraperPipeline:
def __init__(self):
self.create_connection()
self.create_table()
def create_connection(self):
self.conn = sqlite3.connect('imgaes.db')
self.curr = self.conn.cursor()
def create_table(self):
self.curr.execute("""DROP TABLE IF EXISTS images_tb""")
self.curr.execute("""CREATE TABLE images_tb(source text)""")
def save_images(self, item):
self.curr.execute("""INSERT INTO images_tb VALUES(?)""",(
item['src'],
))
self.conn.commit()
def process_item(self, item, spider):
self.save_images(item)
return item
Но, похоже, по какой-то причине это не работает. Я не уверен, передаются ли элементы в конвейер, я предполагаю, что это проблема. Я приношу извинения за недостаток моих знаний, поскольку я новичок в этом, но я заблудился и мне нужна помощь, чтобы разобраться в этом. Я следую этому руководству
Файл json выводится, но я получаю эту ошибку в консоли:
Unhandled error in EventualResult
Traceback (most recent call last):
File "D:python projectstestsvenvlibsite-packagestwistedinternetdefer.py", line 460, in callback
self._startRunCallbacks(result)
File "D:python projectstestsvenvlibsite-packagestwistedinternetdefer.py", line 568, in _startRunCallbacks
self._runCallbacks()
File "D:python projectstestsvenvlibsite-packagestwistedinternetdefer.py", line 654, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "D:python projectstestsvenvlibsite-packagestwistedinternetdefer.py", line 1475, in gotResult
_inlineCallbacks(r, g, status)
--- <exception caught here> ---
File "D:python projectstestsvenvlibsite-packagestwistedinternetdefer.py", line 1418, in _inlineCallbacks
result = g.send(result)
Комментарии:
1. Вы где-нибудь включили этот конвейер?
2. @gangabass Да. Он включен в settings.py
3. какие-либо ошибки в выводе Scrapy log?
4. @gangabass обновил мой пост сообщением об ошибке.
5. Эта обратная трассировка кажется неполной.
Ответ №1:
Я обнаружил, что конвейер не был включен. CrawlerRunner
требуется явная передача объекта settings.
from scrapy.settings import settings
from scrapy.utils.project import get_project_settings
s = get_project_settings
crawl_runner = CrawlerRunner(s)