Sono nuovo di scrapy. Sto scrivendo uno spider progettato per controllare un lungo elenco di URL per i codici di stato del server e, dove appropriato, a quali URL sono reindirizzati. È importante sottolineare che, se esiste una catena di reindirizzamenti, ho bisogno di conoscere il codice di stato e l'url ad ogni salto. Sto usando response.meta ['redirect_urls'] per catturare gli url, ma non sono sicuro di come acquisire i codici di stato - non sembra esserci una meta chiave di risposta per questo.Cattura di codici di stato http con ragno graffiato
Mi rendo conto che potrebbe essere necessario scrivere alcuni middlewear personalizzati per esporre questi valori, ma non sono abbastanza chiaro come registrare i codici di stato per ogni salto, né come accedere a questi valori dallo spider. Ho dato un'occhiata ma non riesco a trovare un esempio di qualcuno che lo faccia. Se qualcuno può indicarmi la giusta direzione, sarebbe molto apprezzato.
Per esempio,
items = []
item = RedirectItem()
item['url'] = response.url
item['redirected_urls'] = response.meta['redirect_urls']
item['status_codes'] = #????
items.append(item)
Modifica - Sulla base del feedback da warawauk e qualche aiuto davvero proattiva dai ragazzi sul canale IRC (freenode #scrappy) sono riuscito a fare questo. Credo che sia un po 'hacky modo eventuali commenti per il miglioramento di benvenuto:
(1) Disattivare il middleware di default nelle impostazioni, e aggiungere il proprio:
DOWNLOADER_MIDDLEWARES = {
'scrapy.contrib.downloadermiddleware.redirect.RedirectMiddleware': None,
'myproject.middlewares.CustomRedirectMiddleware': 100,
}
(2) Crea il tuo CustomRedirectMiddleware nei tuoi middleware .py. Si eredita dalla classe redirectmiddleware principale e cattura il reindirizzamento:
class CustomRedirectMiddleware(RedirectMiddleware):
"""Handle redirection of requests based on response status and meta-refresh html tag"""
def process_response(self, request, response, spider):
#Get the redirect status codes
request.meta.setdefault('redirect_status', []).append(response.status)
if 'dont_redirect' in request.meta:
return response
if request.method.upper() == 'HEAD':
if response.status in [301, 302, 303, 307] and 'Location' in response.headers:
redirected_url = urljoin(request.url, response.headers['location'])
redirected = request.replace(url=redirected_url)
return self._redirect(redirected, request, spider, response.status)
else:
return response
if response.status in [302, 303] and 'Location' in response.headers:
redirected_url = urljoin(request.url, response.headers['location'])
redirected = self._redirect_request_using_get(request, redirected_url)
return self._redirect(redirected, request, spider, response.status)
if response.status in [301, 307] and 'Location' in response.headers:
redirected_url = urljoin(request.url, response.headers['location'])
redirected = request.replace(url=redirected_url)
return self._redirect(redirected, request, spider, response.status)
if isinstance(response, HtmlResponse):
interval, url = get_meta_refresh(response)
if url and interval < self.max_metarefresh_delay:
redirected = self._redirect_request_using_get(request, url)
return self._redirect(redirected, request, spider, 'meta refresh')
return response
(3) A questo punto è possibile accedere all'elenco di reindirizzamenti nel vostro ragno con
request.meta['redirect_status']
Si dovrebbe pubblicare la soluzione come risposta – raben