В настоящее время я разрабатываю REST API с использованием Scrapy и хочу перехватить исключение на уровне контроллера и вернуть соответствующий код состояния HTTP клиенту. Следующие примеры кодов показывают, как возникает исключение:
class MySpider(Spider):
name = 'my_spider'
allowed_domains = ['www.xxxxx.com']
def __init__(self, **kw):
super(MySpider, self).__init__(**kw)
self.base_url = kw['url']
self.action = kw['action']
self.mongo = pymongo.MongoClient(kw['conn'])
def start_requests(self):
if XXX1:
raise XXX1Error('message')
yield Request(self.base_url)
def parse(self, response):
if XXX2:
raise XXX2Error('message')
# Some custom codes
И это примеры кодов в контроллере (здесь я должен использовать подпроцесс, потому что реактор не перезапускается):
@app.route('/xxxx/xxxx/xxxx', methods=['POST'])
def endpoint_entry():
link_json = request.get_json('link')
link = link_json.get('link')
# Initiate a sub-process for the crawling
process = subprocess.Popen(['scrapy', 'crawl', '{0}'.format('my_spider'),
'-a', 'url={0}'.format(link),
'-a', 'action={0}'.format('download'),
'-a', 'conn={0}'.format(MONGO_CONNECTION_STRING)])
process.wait()
if process.returncode != 0:
return 'Something was not right', 400
return 'Scrapping has been processed', 200
Однако похоже, что исключение, возникшее в подпроцессе, не приводит к тому, что подпроцесс имеет код возврата 1, я даже пытался напрямую вызвать sys.exit(1)
вместо raise XXXError('message')
, а return код был по-прежнему 0, и я также пытался использовать сигнал spider_error
, чтобы перехватить возникшее исключение и вызвать новое исключение или выйти из подпроцесса, и это не сработало. Так что я действительно хочу знать, есть ли способ, чтобы это сработало? Или просто нет правильного решения для этого? Буду очень признателен за любой ответ!