Impossibile eliminare alcuni errori sollevati da process_exception
Sto cercando di non mostrare / ricevere qualche errore generato da scrapy all'interno process_responsedi RetryMiddleware. L'errore che lo script incontra quando viene superato il limite massimo di tentativi. Ho usato proxy all'interno del middleware. La cosa strana è che l'eccezione generata dallo script si trova già EXCEPTIONS_TO_RETRYnell'elenco. È del tutto normale che lo script a volte possa superare il numero massimo di tentativi senza alcun successo. Tuttavia, semplicemente non desidero vedere quell'errore anche quando è presente, il che significa sopprimerlo o aggirarlo.
L'errore è come:
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..
Ecco come appare process_responseall'interno RetryMiddleware:
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")
Come posso eliminare gli errori in EXCEPTIONS_TO_RETRY?
PS: l'errore che lo script incontra quando viene raggiunto il limite massimo di tentativi, indipendentemente dal sito scelto.
Risposte
Quando viene raggiunto il numero massimo di tentativi, il metodo come parse_error()dovrebbe gestire qualsiasi errore se è presente nel tuo 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
Tuttavia, ho pensato di suggerire un approccio completamente diverso qui. Se segui il percorso seguente, non hai bisogno di alcun middleware personalizzato. Tutto, incluso il nuovo tentativo di logica, è già presente nello spider.
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)
Non dimenticare di aggiungere la seguente riga per ottenere il suddetto risultato dal suggerimento sopra:
custom_settings = {
'DOWNLOADER_MIDDLEWARES': {
'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
}
}
A proposito, sto usando scrapy 2.3.0.
Forse il problema non è dalla tua parte, ma potrebbe esserci qualcosa di sbagliato nel sito di terze parti. Forse c'è un errore di connessione sul loro server o forse è sicuro in modo che nessuno possa accedervi.
Perché l'errore dice anche che l'errore è con la parte in grado di spegnerlo o non funziona correttamente, forse prima controlla se il sito di terze parti funziona quando richiesto. Prova a contattarli se puoi.
Perché l'errore non è da parte tua, è dalla fine della festa come dice l'errore.
Questa domanda è simile a Scrapy - Imposta timeout connessione TCP
Prova a correggere il codice nel raschietto stesso. A volte avere una cattiva funzione di analisi può portare a un errore del tipo che stai descrivendo. Una volta corretto il codice, è andato via per me.