使用Twisted的爬虫,当getPage超时错误时我该怎么办?

1 投票
1 回答
702 浏览
提问于 2025-04-17 18: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 运行时,它不会再接收新的事件了。

你们有没有遇到过类似的问题?非常感谢你们的帮助!

1 个回答

2

看起来当反应器在运行时,它就不会再接收到新的事件了。

其实不是这样的。事件只有在反应器运行的时候才会发生!

你没有分享使用了 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
    ...

撰写回答