【发布时间】:2021-07-30 15:57:22
【问题描述】:
目前我正在开发一个作为 API 运行的蜘蛛项目,因此我对在 HTTP 服务器中运行 scrapy 进行了一些研究。为了简单起见,我选择了 Python Klein,基本上是这样的:
https://github.com/betinacosta/scrapy-klein-tutorial/blob/master/README%5BEN-US%5D.md
目前,我的代码如下所示(Python 3.9):
import json
import os
from klein import Klein
from scrapy import signals
from scrapy.crawler import CrawlerRunner
from twisted.web.server import Site
Site.displayTracebacks = False
class TwistedRunner(CrawlerRunner):
def crawl(self, Spider, *args, **kwargs):
self.items = []
# create spider instance
crawler = self.create_crawler(Spider)
crawler.signals.connect(self.storeItem, signals.item_scraped)
# create deferred crawler-object and register callback
deferred = self._crawl(crawler, *args, **kwargs)
deferred.addCallback(self.getItems)
return deferred
def storeItem(self, item):
self.items.append(item)
def getItems(self, item):
return self.items
def getSpiderResult(output):
"""Format spider result"""
return json.dumps([dict(item) for item in output])
class Router(object):
app = Klein()
scrapeArgument = os.getenv('argument', 'product').encode()
@app.route('/<path:catchall>', methods=['POST', 'GET'])
def catchAll(self, request, catchall):
"""catch-all route"""
request.redirect('/')
@app.route('/', methods=['GET', 'POST'])
def scrape(self, request):
"""Serve request for scrape"""
if self.scrapeArgument not in request.args:
return None
Runner = TwistedRunner()
product=request.args.get(self.scrapeArgument).pop()
a = Runner.crawl(MySpiderCls, product=product)
a.addCallback(getSpiderResult)
return a
if __name__ == '__main__':
Router = Router()
Router.app.run(os.getenv('address', '0.0.0.0'), os.getenv('port', 8080))
这工作正常,正如预期的那样。现在,我很想从这一点上运行多个蜘蛛。文档对此非常清楚:
https://docs.scrapy.org/en/latest/topics/practices.html
但是,当我做类似的事情时
runner = CrawlerRunner()
runner.crawl(MySpider1)
runner.crawl(MySpider2)
d = runner.join()
我看到所有蜘蛛都在运行,但是一旦第一个蜘蛛完成,HTTP 请求就完成了。此时,可能还有蜘蛛尚未完成,因此我缺少项目。为了说明这种行为,请参阅一些示例日志:
2021-07-29 21:14:27+0200 [-] save item
2021-07-29 21:14:27+0200 [-] (TCP Port 6024 Closed)
2021-07-29 21:14:27+0200 [-] "127.0.0.1" - - [29/Jul/2021:19:14:27 +0000] "GET /?product=anything HTTP/1.1" 200 3 "-" "curl/7.78.0"
2021-07-29 21:14:27+0200 [-] save item
如您所见,最终保存的项目将永远不会回显给用户,因为请求已在上面完成。
有人知道如何通过这个设置运行多个蜘蛛吗?另外,如果有什么我没有按照scrapy-doctrine做的事情,请告诉我。
谢谢!
【问题讨论】:
标签: python asynchronous scrapy twisted