यह इतना आसान नहीं है क्योंकि स्केपर गैर-अवरुद्ध है और एक ईवेंट लूप में काम करता है; यह ट्विस्टेड इवेंट लूप का उपयोग करता है, और ट्विस्टेड इवेंट लूप पुनरारंभ करने योग्य नहीं है, इसलिए आप crawler.start(); data = crawler.data
नहीं लिख सकते हैं - crawler.start()
प्रक्रिया के बाद हमेशा के लिए चलती है, जब तक कि इसे मार या समाप्त नहीं किया जाता है, तब तक पंजीकृत कॉलबैक को कॉल करना।
ये जवाब प्रासंगिक हो सकता है:
आप अपने अनुप्रयोग में एक घटना पाश का उपयोग करते हैं (उदाहरण के लिए यदि आप एक मुड़ या तूफान वेब सर्वर है) तो यह है डिस्क पर संग्रहीत किए बिना क्रॉल से डेटा प्राप्त करना संभव है। विचार आइटम_स्क्रैड सिग्नल को सुनना है। मैं इसे अच्छे बनाने के लिए निम्नलिखित सहायक उपयोग कर रहा हूँ:
import collections
from twisted.internet.defer import Deferred
from scrapy.crawler import Crawler
from scrapy import signals
def scrape_items(crawler_runner, crawler_or_spidercls, *args, **kwargs):
"""
Start a crawl and return an object (ItemCursor instance)
which allows to retrieve scraped items and wait for items
to become available.
Example:
.. code-block:: python
@inlineCallbacks
def f():
runner = CrawlerRunner()
async_items = scrape_items(runner, my_spider)
while (yield async_items.fetch_next):
item = async_items.next_item()
# ...
# ...
This convoluted way to write a loop should become unnecessary
in Python 3.5 because of ``async for``.
"""
crawler = crawler_runner.create_crawler(crawler_or_spidercls)
d = crawler_runner.crawl(crawler, *args, **kwargs)
return ItemCursor(d, crawler)
class ItemCursor(object):
def __init__(self, crawl_d, crawler):
self.crawl_d = crawl_d
self.crawler = crawler
crawler.signals.connect(self._on_item_scraped, signals.item_scraped)
crawl_d.addCallback(self._on_finished)
crawl_d.addErrback(self._on_error)
self.closed = False
self._items_available = Deferred()
self._items = collections.deque()
def _on_item_scraped(self, item):
self._items.append(item)
self._items_available.callback(True)
self._items_available = Deferred()
def _on_finished(self, result):
self.closed = True
self._items_available.callback(False)
def _on_error(self, failure):
self.closed = True
self._items_available.errback(failure)
@property
def fetch_next(self):
"""
A Deferred used with ``inlineCallbacks`` or ``gen.coroutine`` to
asynchronously retrieve the next item, waiting for an item to be
crawled if necessary. Resolves to ``False`` if the crawl is finished,
otherwise :meth:`next_item` is guaranteed to return an item
(a dict or a scrapy.Item instance).
"""
if self.closed:
# crawl is finished
d = Deferred()
d.callback(False)
return d
if self._items:
# result is ready
d = Deferred()
d.callback(True)
return d
# We're active, but item is not ready yet. Return a Deferred which
# resolves to True if item is scraped or to False if crawl is stopped.
return self._items_available
def next_item(self):
"""Get a document from the most recently fetched batch, or ``None``.
See :attr:`fetch_next`.
"""
if not self._items:
return None
return self._items.popleft()
एपीआई motor, async चौखटे के लिए एक MongoDB ड्राइवर से प्रेरित है। Scrape_items का उपयोग करके आप मोड़ या टर्ननाडो कॉलबैक से सामान प्राप्त कर सकते हैं जैसे ही वे स्क्रैप किए जाते हैं, वैसे ही जैसे आप मोंगोडीबी क्वेरी से आइटम कैसे प्राप्त करते हैं।
स्रोत
2016-11-21 08:17:25