Meta

  • 信息传递

    • 在创建REQEUSTS对象时设置meta

      yield scrapy.FormRequest(meta={"keyword": keyword, "sta_date": sta_date})
    • REQUESTS对象流转中修改meta

      • download_slot
      • download_latency
    • RESPONSE对象中获取meta

      #等同于response.request.meta
      response.meta
  • 自定义单个请求的配置

    https://docs.scrapy.org/en/latest/topics/request-response.html?highlight=meta#topics-request-meta
    • dont_redirect

      如果设置为True, 当前请求则不会重定向.

    • dont_retry

      如果设置为True, 当前请求则不会重试.

    • max_retry_times

      设置最大重试次数.

    • dont_merge_cookiescookiejar

      操作cookie的meta参数, 但是不建议这么使用, 一般来说我们直接设置

      request.headers["cookie"] = "......."
    • proxy

      设置请求代理

      request.meta['proxy'] = '127.0.0.1:8989'
    • 设置优先级

      如果你设置了优先级队列, 那么可以只是priority参数决定请求的顺序

      # 数字越小, 优先级越高
      request.meta['priority'] = 10

异常处理

异常处理时scrapy最大的痛点, 因为你一定要熟悉事件的流向.
  • Spiders组件

    在异常处理中, Spider组件其实是处理RESPONSE对象或者请求之后产生的异常, 一般作为一次请求异常处理的终点, 也就是指定的回调函数errorback.

    • errorback

      处理不可控的异常

          def start_request(self):
              yield scrapy.FormRequest(errorback=self.process_error)
          
          def process_error(self, failure):
              print(failure)
              # 记录异常
              # 发送通知
              # 重做任务
              ...
      • failure.request

        当前异常请求对象

      • failure.value

        当前的异常对象

    • CloseSpider

      遇到像cookie过期, 账号警告, 代理池空了这样严重的错, 需要关闭实例, 可抛出CloseSpider异常, 该异常最终会流向ENGINE后关闭爬虫实例.

      from scrapy.exceptions import CloseSpider
  • 中间件

    处理可控的异常

    def process_exception(self, request, exception, spider):
        pass
    • 返回None

      由下一层中间件继续处理, 如果你指定了errback, 最终会到达errback

    • 返回REPONSE对象

      中断异常链, 返回的RESPONSE对象会到达Spiders组件

    • 返回Request

      中断异常链, 返回的Request对象将到达ENGINESCHEDULER重新调度.

          def process_exception(self, request, exception, spider):
              # 如果异常是cookie池空了, 可以在这里完成cookie池的补充
              # 补充cookie池
              if isinstance(exception, IndexError):
                  # 我已经知道异常产生原因, 所以免除当前重试次数的计数
                  retry_times = request.meta.get('retry_times', 1)
                  request.meta['retry_times'] = retry_times - 1
                  return request
Last modification:September 21, 2022
如果觉得我的文章对你有用,请随意赞赏