首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Scrapy:非阻塞暂停

Scrapy:非阻塞暂停
EN

Stack Overflow用户
提问于 2016-05-02 22:18:03
回答 3查看 3.6K关注 0票数 22

我有个问题。我需要停止函数的执行一段时间,但不能停止整个解析的实现。也就是说,我需要一个非阻塞的暂停。

它看起来像这样:

class ScrapySpider(Spider):
    name = 'live_function'

    def start_requests(self):
        yield Request('some url', callback=self.non_stop_function)

    def non_stop_function(self, response):
        for url in ['url1', 'url2', 'url3', 'more urls']:
            yield Request(url, callback=self.second_parse_function)

        # Here I need some function for sleep only this function like time.sleep(10)

        yield Request('some url', callback=self.non_stop_function)  # Call itself

    def second_parse_function(self, response):
        pass

函数non_stop_function需要停止一段时间,但它不应该阻塞输出的其余部分。

如果我插入time.sleep() -它会停止整个解析器,但我不需要它。是否可以使用twisted或其他方法停止一个函数?

原因:我需要创建一个非阻塞函数,它将每隔n秒解析一次网站页面。在那里,她将获得urls并填充10秒钟。已经获得的URL将继续工作,但主要功能需要休眠。

更新

感谢TkTechviach。一个答案帮助我理解了如何创建一个挂起的Request,第二个答案是如何激活它。这两个答案是相辅相成的,我为Scrapy做了一个很好的非阻塞暂停:

def call_after_pause(self, response):
    d = Deferred()
    reactor.callLater(10.0, d.callback, Request(
        'https://example.com/',
        callback=self.non_stop_function,
        dont_filter=True))
    return d

并对我的请求使用此函数:

yield Request('https://example.com/', callback=self.call_after_pause, dont_filter=True)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-05 19:41:54

Request对象有callback参数,请尝试使用该参数。我的意思是,创建一个包装self.second_parse_functionpauseDeferred

这是我的脏的和未测试的示例,更改的行被标记。

class ScrapySpider(Spider):
    name = 'live_function'

    def start_requests(self):
        yield Request('some url', callback=self.non_stop_function)

    def non_stop_function(self, response):

        parse_and_pause = Deferred()  # changed
        parse_and_pause.addCallback(self.second_parse_function) # changed
        parse_and_pause.addCallback(pause, seconds=10)  # changed

        for url in ['url1', 'url2', 'url3', 'more urls']:
            yield Request(url, callback=parse_and_pause)  # changed

        yield Request('some url', callback=self.non_stop_function)  # Call itself

    def second_parse_function(self, response):
        pass

如果这种方法对您有效,那么您可以创建一个函数,它根据规则构造一个Deferred对象。它可以通过如下方式实现:

def get_perform_and_pause_deferred(seconds, fn, *args, **kwargs):
    d = Deferred()
    d.addCallback(fn, *args, **kwargs)
    d.addCallback(pause, seconds=seconds)
    return d

下面是可能的用法:

class ScrapySpider(Spider):
    name = 'live_function'

    def start_requests(self):
        yield Request('some url', callback=self.non_stop_function)

    def non_stop_function(self, response):
        for url in ['url1', 'url2', 'url3', 'more urls']:
            # changed
            yield Request(url, callback=get_perform_and_pause_deferred(10, self.second_parse_function))

        yield Request('some url', callback=self.non_stop_function)  # Call itself

    def second_parse_function(self, response):
        pass
票数 7
EN

Stack Overflow用户

发布于 2016-05-02 22:44:02

如果您正在尝试使用它来进行速率限制,那么您可能只想使用DOWNLOAD_DELAY

Scrapy只是Twisted之上的一个框架。在很大程度上,你可以像对待任何其他扭曲的应用程序一样对待它。不需要调用sleep,只需返回下一个请求make,并告诉twisted稍等片刻。例如:

from twisted.internet import reactor, defer

def non_stop_function(self, response)
    d = defer.Deferred()
    reactor.callLater(10.0, d.callback, Request(
        'some url',
        callback=self.non_stop_function
    ))
    return d
票数 6
EN

Stack Overflow用户

发布于 2017-02-23 11:45:47

发问者已经在问题的更新中提供了答案,但我想给出一个稍微更好的版本,以便它可以重用于任何请求。

# removed...
from twisted.internet import reactor, defer

class MySpider(scrapy.Spider):
    # removed...

    def request_with_pause(self, response):
        d = defer.Deferred()
        reactor.callLater(response.meta['time'], d.callback, scrapy.Request(
            response.url,
            callback=response.meta['callback'],
            dont_filter=True, meta={'dont_proxy':response.meta['dont_proxy']}))
        return d

    def parse(self, response):
        # removed....
        yield scrapy.Request(the_url, meta={
                            'time': 86400, 
                            'callback': self.the_parse, 
                            'dont_proxy': True
                            }, callback=self.request_with_pause)

作为解释,Scrapy使用Twisted来异步管理请求,所以我们也需要Twisted的工具来处理延迟的请求。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36984696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档