无法摆脱由进程\u异常引发的某些错误

2024-04-20 07:46:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图不在RetryMiddleware中的process_response内显示/获取scrapy抛出的一些错误。脚本在超过最大重试限制时遇到的错误。我在中间件中使用了代理。奇怪的是,脚本抛出的异常已经在EXCEPTIONS_TO_RETRY列表中。脚本有时可能会跨越最大重试次数而没有任何成功,这是完全可以接受的。然而,我只是不希望看到这个错误,即使它存在,这意味着抑制或绕过它

错误如下:

Traceback (most recent call last):
  File "middleware.py", line 43, in process_request
    defer.returnValue((yield download_func(request=request,spider=spider)))
twisted.internet.error.TCPTimedOutError: TCP connection timed out: 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond..

这就是RetryMiddleware中的process_response的样子:

class RetryMiddleware(object):
    cus_retry = 3
    EXCEPTIONS_TO_RETRY = (defer.TimeoutError, TimeoutError, DNSLookupError, \
        ConnectionRefusedError, ConnectionDone, ConnectError, \
        ConnectionLost, TCPTimedOutError, TunnelError, ResponseFailed)

    def process_exception(self, request, exception, spider):
        if isinstance(exception, self.EXCEPTIONS_TO_RETRY) \
                and not request.meta.get('dont_retry', False):
            return self._retry(request, exception, spider)

    def _retry(self, request, reason, spider):
        retries = request.meta.get('cus_retry',0) + 1
        if retries<=self.cus_retry:
            r = request.copy()
            r.meta['cus_retry'] = retries
            r.meta['proxy'] = f'https://{ip:port}'
            r.dont_filter = True
            return r
        else:
            print("done retrying")

如何消除EXCEPTIONS_TO_RETRY中的错误?

PS:无论我选择哪个站点,当达到最大重试限制时脚本遇到的错误


Tags: toself脚本request错误exceptionconnectionprocess
3条回答

当达到最大重试次数时,类似parse_error()的方法应该处理任何错误,如果它在您的spider中:

def start_requests(self):
    for start_url in self.start_urls:
        yield scrapy.Request(start_url,errback=self.parse_error,callback=self.parse,dont_filter=True)

def parse_error(self, failure):
    # print(repr(failure))
    pass

然而,我想在这里提出一种完全不同的方法。如果您遵循以下路线,那么根本不需要任何自定义中间件。包括重试逻辑在内的所有内容都已经存在于爬行器中

class mySpider(scrapy.Spider):
    name = "myspider"
    start_urls = [
        "some url",
    ]

    proxies = [] #list of proxies here
    max_retries = 5
    retry_urls = {}

    def parse_error(self, failure):
        proxy = f'https://{ip:port}'
        retry_url = failure.request.url
        if retry_url not in self.retry_urls:
            self.retry_urls[retry_url] = 1
        else:
            self.retry_urls[retry_url] += 1
        
        if self.retry_urls[retry_url] <= self.max_retries:
            yield scrapy.Request(retry_url,callback=self.parse,meta={"proxy":proxy,"download_timeout":10}, errback=self.parse_error,dont_filter=True)
        else:
            print("gave up retrying")

    def start_requests(self):
        for start_url in self.start_urls:
            proxy = f'https://{ip:port}'
            yield scrapy.Request(start_url,callback=self.parse,meta={"proxy":proxy,"download_timeout":10},errback=self.parse_error,dont_filter=True)

    def parse(self,response):
        for item in response.css().getall():
            print(item)

不要忘记添加以下行,以从上述建议中获得上述结果:

custom_settings = {
    'DOWNLOADER_MIDDLEWARES': {
        'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
    }
}

顺便说一下,我正在使用scrapy 2.3.0

也许问题不在你这边,但第三方网站可能有问题。可能他们的服务器上有连接错误,或者可能是安全的,所以没有人可以访问它

导致错误的原因甚至表示该错误与该方有关。如果该方已关闭或工作不正常,则可能首先检查第三方站点是否在请求时工作。如果可以的话,试着联系他们

因为错误不在你这一方,正如错误所说,它在这一方

这个问题类似于Scrapy - Set TCP Connect Timeout

尝试修复刮板本身中的代码。有时,如果解析函数不正确,可能会导致所描述的那种错误。一旦我修正了密码,它就消失了

相关问题 更多 >