在 scrapy 项目中捕获重定向响应 status/history

Capture redirect response status/history in scrapy item

我确定有人问过这个问题,但我这辈子都找不到答案。我所追求的是 requests 包中 response.history 的 scrapy 等价物。我有一个带有 ID 和 url 的数据框。对于每个 url,我想要 return 最终响应 final_url 和响应历史记录。使用 requests,代码如下所示:

import requests
import pandas as pd
import numpy as np

def get_responses(url):
    try:
        r = requests.head(url, allow_redirects = True)
        r.raise_for_status()
        return [r.status_code, r.url, '; '.join([str(resp.status_code) for resp in r.history])]
    except requests.exceptions.HTTPError as errh:
        return [errh, None, None]
    except requests.exceptions.ConnectionError as errc:
        return ['error connecting', None, None]
    except requests.exceptions.Timeout as errt:
        return ['timeout error', None, None]
    except requests.exceptions.RequestException as err:
        return ['oops: something else', None, None]

df[['response', 'response_url', 'response_history']] = [get_responses(x) for x in df['formatted_url'].values]

输出看起来像这样,这就是我想要的:

id formatted_url response response_url response_history
1 http://WWW.BARHARBORINFO.COM 200 https://www.visitbarharbor.com/ 301; 301

问题是我有几千个网站正在尝试获取此信息,这需要很长时间才能 运行。输入 scrapy。除了响应历史记录之外,我已经弄清楚如何从 scrapy 获得相同的输出。有没有办法在 scrapy 中做到这一点?

你绝对可以做到这一点,它看起来甚至已经被 Scrapy 的 Redirect Middleware 支持,因为如果不支持,那么覆盖重定向中间件以启用此功能应该不会太难.

正如您在中间件代码中看到的:

redirected.meta['redirect_times'] = redirects
redirected.meta['redirect_ttl'] = ttl - 1
redirected.meta['redirect_urls'] = request.meta.get('redirect_urls', []) + [request.url]
redirected.meta['redirect_reasons'] = request.meta.get('redirect_reasons', []) + [reason]

redirected 是中间件正在创建的响应,它最终将传递给您应该控制的请求回调。

据我所知,response.status 作为 redirect_reason 传递,所以基本上从您的回调方法中您可以获得:

response.meta['redirect_reasons']

您将能够获得该特定请求的“重定向历史记录”。