【问题标题】:Crawler using twisted, what can I do when getPage get a timeout error?爬虫使用twisted,getPage遇到超时错误怎么办?
【发布时间】:2013-03-08 09:05:23
【问题描述】:

我使用twisted 及其deferredGenerator 编写了一个爬虫。 以下是关于我的问题的代码:

      @defer.deferredGenerator
      def getReviewsFromPage(self,title,params):

          def deferred1(page):
              d = defer.Deferred()
              reactor.callLater(1,d.callback,self.parseReviewJson(page))
              return d

          def deferred2(dataL,title):
              d = defer.Deferred()
              reactor.callLater(1,d.callback,self.writeToCSV(dataL,title=title))
              return d

          cp = 1
          #for cp in range(1,15000):
          while self.running:
              print cp
              params["currentPageNum"] = cp

              url = self.generateReviewUrl(self.urlPrefix,params = params)
              print url

              wfd = defer.waitForDeferred(getPage(url,timeout=10))
              yield wfd
              page = wfd.getResult()
              wfd = defer.waitForDeferred(deferred1(page))
              yield wfd
              dataList = wfd.getResult()
              wfd = defer.waitForDeferred(deferred2(dataList,title))
              yield wfd
              cp = cp+1

我使用生成器

    self.getReviewsFromPage(title,params)
    reactor.run()

我的问题是: 当函数'getPage'出现超时错误时,我该如何处理错误并再次抓取错误页面?我在getPage中添加了一次addErrback,并想调用getPage,但似乎在reactor运行时,它不会再收到新事件了。

你们中有人遇到过同样的问题吗?非常感谢您的帮助

【问题讨论】:

    标签: python timeout twisted web-crawler reactor


    【解决方案1】:

    好像reactor在运行的时候,不会再收到新的事件了。

    事实并非如此。事件在反应器运行时发生!

    你没有分享使用addErrback的代码版本,所以我看不出你的使用方式是否有问题。但是,由于您已经在使用 deferredGenerator,因此更惯用的方法是:

    page = None
    for i in range(numRetries):
        wfd = defer.waitForDeferred(getPage(url,timeout=10))
        yield wfd
        try:
            page = wfd.getResult()
        except TimeoutError:
            # Do nothing, let the loop continue
            pass
        else:
            # Success, exit the loop
            break
    if page is None:
        # Handle the timeout for real
        ...
    else:
        # Continue processing
        ...
    

    【讨论】:

    • 感谢您的回答。我昨天解决了这个问题,解决方法和你的很相似,从wfd.getResult获取页面并检查其类型是否为NoneType(我不知道该类型是否与errback有任何关系。我添加的功能errback 什么都不返回)。你给出了一个合适的解决方案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2015-06-19
    • 2017-11-02
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多