【发布时间】:2015-12-19 21:12:27
【问题描述】:
API 应该允许包含用户想要抓取的 URL 的任意 HTTP 获取请求,然后 Flask 应该返回抓取的结果。
以下代码适用于第一个 http 请求,但是在 twisted reactor 停止后,它不会重新启动。我什至可能没有以正确的方式解决这个问题,但我只想在 Heroku 上放置一个 RESTful scrapy API,到目前为止我能想到的就是我所能想到的。
有没有更好的方法来构建这个解决方案?或者我怎样才能让scrape_it 在不停止扭曲反应器(无法再次启动)的情况下返回?
from flask import Flask
import os
import sys
import json
from n_grams.spiders.n_gram_spider import NGramsSpider
# scrapy api
from twisted.internet import reactor
import scrapy
from scrapy.crawler import CrawlerRunner
from scrapy.xlib.pydispatch import dispatcher
from scrapy import signals
app = Flask(__name__)
def scrape_it(url):
items = []
def add_item(item):
items.append(item)
runner = CrawlerRunner()
d = runner.crawl(NGramsSpider, [url])
d.addBoth(lambda _: reactor.stop()) # <<< TROUBLES HERE ???
dispatcher.connect(add_item, signal=signals.item_passed)
reactor.run(installSignalHandlers=0) # the script will block here until the crawling is finished
return items
@app.route('/scrape/<path:url>')
def scrape(url):
ret = scrape_it(url)
return json.dumps(ret, ensure_ascii=False, encoding='utf8')
if __name__ == '__main__':
PORT = os.environ['PORT'] if 'PORT' in os.environ else 8080
app.run(debug=True, host='0.0.0.0', port=int(PORT))
【问题讨论】:
-
能否提供回溯错误或其他信息?另外为什么不删除这条线
d.addBoth(lambda _: reactor.stop())并在reactor.run()之后调用reactor.stop 我假设它出错了,因为当它进入函数时reactor 可能处于启动状态或停止状态。不能保证。 -
为什么要使用 Scrapy?还有其他方法可以废弃页面
-
@ahmed 我的问题是建立一个异步队列来拉出许多页面,然后爬出这些页面上的链接。你会为此推荐什么?
标签: python heroku flask scrapy twisted