天天看點

python twisted和flask_python – 如何內建Flask和Scrapy?

在蜘蛛面前添加HTTP伺服器并不容易.有幾種選擇.

1. Python子流程

如果你真的隻限于Flask,如果你不能使用其他任何東西,隻有将Scrapy與Flask內建的方法是為每個蜘蛛爬行啟動外部程序,如其他答案所建議的那樣(注意你的子程序需要在适當的Scrapy項目中生成)目錄).

所有示例的目錄結構應如下所示,我使用的是dirbot test project

> tree -L 1

├── dirbot

├── README.rst

├── scrapy.cfg

├── server.py

└── setup.py

以下是在新流程中啟動Scrapy的代碼示例:

# server.py

import subprocess

from flask import Flask

app = Flask(__name__)

@app.route('/')

def hello_world():

"""

Run spider in another process and store items in file. Simply issue command:

> scrapy crawl dmoz -o "output.json"

wait for this command to finish, and read output.json to client.

"""

spider_name = "dmoz"

subprocess.check_output(['scrapy', 'crawl', spider_name, "-o", "output.json"])

with open("output.json") as items_file:

return items_file.read()

if __name__ == '__main__':

app.run(debug=True)

将上面儲存為server.py并通路localhost:5000,您應該可以看到已删除的項目.

2. Twisted-Klein Scrapy

其他更好的方法是使用一些現有項目,将Twisted與Werkzeug內建,并顯示類似于Flask的API,例如: Twisted-Klein. Twisted-Klein允許您在與Web伺服器相同的過程中異步運作您的蜘蛛.它更好,因為它不會阻止每個請求,它允許您簡單地從HTTP路由請求處理程式傳回Scrapy / Twisted延遲.

以下代碼片段将Twisted-Klein與Scrapy內建,請注意您需要建立自己的CrawlerRunner基類,以便抓取工具收集項目并将其傳回給調用者.這個選項有點進階,你在與Python伺服器相同的過程中運作Scrapy蜘蛛,項目不存儲在檔案中但存儲在記憶體中(是以沒有像前面的例子那樣的磁盤寫入/讀取).最重要的是它是異步的,它都在一個Twisted反應堆中運作.

# server.py

import json

from klein import route, run

from scrapy import signals

from scrapy.crawler import CrawlerRunner

from dirbot.spiders.dmoz import DmozSpider

class MyCrawlerRunner(CrawlerRunner):

"""

Crawler object that collects items and returns output after finishing crawl.

"""

def crawl(self, crawler_or_spidercls, *args, **kwargs):

# keep all items scraped

self.items = []

# create crawler (Same as in base CrawlerProcess)

crawler = self.create_crawler(crawler_or_spidercls)

# handle each item scraped

crawler.signals.connect(self.item_scraped, signals.item_scraped)

# create Twisted.Deferred launching crawl

dfd = self._crawl(crawler, *args, **kwargs)

# add callback - when crawl is done cal return_items

dfd.addCallback(self.return_items)

return dfd

def item_scraped(self, item, response, spider):

self.items.append(item)

def return_items(self, result):

return self.items

def return_spider_output(output):

"""

:param output: items scraped by CrawlerRunner

:return: json with list of items

"""

# this just turns items into dictionaries

# you may want to use Scrapy JSON serializer here

return json.dumps([dict(item) for item in output])

@route("/")

def schedule(request):

runner = MyCrawlerRunner()

spider = DmozSpider()

deferred = runner.crawl(spider)

deferred.addCallback(return_spider_output)

return deferred

run("localhost", 8080)

将上面儲存在檔案server.py中并在Scrapy項目目錄中找到它,

現在打開localhost:8080,它将啟動dmoz spider并将作為json的項目傳回浏覽器.

3. ScrapyRT

當您嘗試在蜘蛛面前添加HTTP應用程式時,會出現一些問題.例如,您有時需要處理蜘蛛日志(在某些情況下您可能需要它們),您需要以某種方式處理蜘蛛異常等.有些項目允許您以更簡單的方式向蜘蛛添加HTTP API,例如ScrapyRT.這是一個将HTTP伺服器添加到Scrapy蜘蛛并為您處理所有問題的應用程式(例如處理日志記錄,處理蜘蛛錯誤等).

是以在安裝ScrapyRT後你隻需要這樣做:

> scrapyrt

免責聲明:我是ScrapyRt的作者之一.