Пример #1
0
    def process_response(self, request, response, spider):
        """
        要考虑两种情况,一是被封,二是ip 失效
        :param request:
        :param response:
        :param spider:
        :return:
        """
        proxy_str = request.meta['proxy']
        proxy = ProxyItem.parse(proxy_str)
        # 持有的是方法,只有一个实例,所以并发时 self.proxy 应该是不准确的,需从 request 获取

        if isinstance(response, ErrorResponse):
            proxy_manager.fail(proxy)
            return self.on_request_error(request, response, spider)
        code, _ = douyin.parse_result(response.body.decode())
        if code == 1:
            proxy_manager.success(proxy)
        elif code == 2:
            proxy_manager.banned(proxy)
            if douyin_spider.ANONYMOUS:
                # 匿名则忽略并继续 ,不匿名返回处理
                return self.on_request_error(request, response, spider)
            else:
                return response
        else:
            proxy_manager.fail(proxy)
            return self.on_request_error(request, response, spider)
        return response
Пример #2
0
 def process_exception(self, request, exception, spider):
     proxy_str = request.meta['proxy']
     proxy = ProxyItem.parse(proxy_str)
     if isinstance(exception, IgnoreRequest):
         # 已忽略
         return self.get_error_response(exception)
     else:
         # 检查是否是已知的错误,如果是未知错误,可能需要记录处理
         fail_exception_list = [
             error.ConnectError,
             error.ConnectionRefusedError,
             error.TCPTimedOutError,
             error.TimeoutError,  # 超过设定的 timeout
             ResponseNeverReceived,
         ]
         for e in fail_exception_list:
             if isinstance(exception, e):
                 # 被拒绝
                 # 此处不调用 fail,返回 response 之后会在 process_response 中处
                 # proxy_manager.fail(proxy)
                 return self.get_error_response(exception)
     log.error("process_exception")
     log.error(f'proxy is {proxy}')
     log.error(type(exception))
     log.error(exception)
Пример #3
0
    def process_exception(self, request, exception, spider):
        """
        处理异常
        如果超时了,则抛出一个 ErrorResponse,交给 process_response 处理

        如果其返回 None ,Scrapy将会继续处理该异常,接着调用已安装的其他中间件的 process_exception() 方法,直到所有中间件都被调用完毕,则调用默认的异常处理。
        如果其返回一个 Response 对象,则已安装的中间件链的 process_response() 方法被调用。Scrapy将不会调用任何其他中间件的 process_exception() 方法。
        如果其返回一个 Request 对象, 则返回的request将会被重新调用下载。这将停止中间件的 process_exception() 方法执行,就如返回一个response的那样。
        """
        # 检查是否是已知的错误,如果是未知错误,可能需要记录处理
        fail_exception_list = [
            ConnectError,
            TunnelError,
            ResponseFailed,
        ]
        for e in fail_exception_list:
            if isinstance(exception, e):
                # 被拒绝
                # 此处不调用 fail,返回 response 之后会在 process_response 中处
                # proxy_manager.fail(proxy)
                return self.get_error_response(exception)
        if 'proxy' in request.meta:
            proxy_str = request.meta['proxy']
            proxy = ProxyItem.parse(proxy_str)
        else:
            proxy = ''
        log.error(f"process_exception 还有未处理的异常"
                  f"\nproxy is {proxy}"
                  f"\ntype is {type(exception)}"
                  f"\nexception is {exception}")
        return self.get_error_response(exception)
Пример #4
0
 def _execute(self, sql, proxy=None, key=None):
     """执行"""
     if proxy:
         if isinstance(proxy, str):
             sql = sql.format(now=int(time.time()), key=key, **ProxyItem.parse(proxy))
         elif isinstance(proxy, ProxyItem):
             sql = sql.format(now=int(time.time()), key=key, **proxy)
     # print(f'执行 {sql}')
     asyncio.get_event_loop().run_until_complete(self.manager.execute(sql))
Пример #5
0
    def process_response(self, request, response, spider):
        """
        处理回复
        如果是 ErrorResponse 则记录失败
        否则判断并记录成功

        如果其返回一个 Response (可以与传入的response相同,也可以是全新的对象), 该response会被在链中的其他中间件的 process_response() 方法处理。
        如果其返回一个 Request 对象,则中间件链停止, 返回的request会被重新调度下载。处理类似于 process_request() 返回request所做的那样。
        如果其抛出一个 IgnoreRequest 异常,则调用request的errback(Request.errback)。 如果没有代码处理抛出的异常,则该异常被忽略且不记录(不同于其他异常那样)。
        """
        if not ('proxy' in request.meta):
            if isinstance(response, ErrorResponse):
                print(f'忽略')
                raise IgnoreRequest()
            else:
                return response
        proxy_str = request.meta['proxy']
        proxy = ProxyItem.parse(proxy_str)
        if isinstance(response, ErrorResponse):
            self.unique_proxy = ''
            # 请求失败
            print('请求失败,记录失败,重新请求')
            proxy_manager.fail(proxy)
            return self.on_request_error(request, response, spider)
        elif not self.is_success_response(response):
            self.unique_proxy = ''
            # 回复解析失败
            print('回复解析失败,记录失败,重新请求')
            if self.is_banned_response(response):
                proxy_manager.banned(proxy)
            else:
                proxy_manager.fail(proxy)
            return self.on_request_error(request, response, spider)
        else:
            # 回复成功
            if not self.use_unique_proxy:
                # 唯一代理就不用记录了
                print('回复解析成功,记录成功')
                proxy_manager.success(proxy)
        return response