Scrapy: return 下载器中间件中的 FormRequest

Scrapy: return FormRequest in Downloader Middleware

我正在抓取的网站有时会重定向到一个页面,其中包含我想在下载器中间件中处理的表单。这个想法是每次发生这种重定向时,它都会自动提交表单并检索结果。我的中间件看起来像:

from scrapy import FormRequest

class SubmitFormMiddleware:
    def process_response(self, request, response, spider):
        if response.css('form.loginbox').getall():
            post_form_url = response.css('form.loginbox::attr(action)').get()
            return FormRequest(url=response.urljoin(post_form_url),
                                     formdata={'username': 'my_username',
                                               'password': 'my_password',
                                               'data_selection': 'all'
                                               },
                                     method='POST',
                                     dont_filter=True)
        else:
            return response

这不起作用,因为我没有定义任何回调(我不应该因为我在中间件中):

NotImplementedError: DefaultSpider.parse callback is not defined

如果我只想 return 一个请求,我会有这样的请求:

redirected = request.replace(url=response.urljoin(post_form_url))
return self._redirect(redirected, request, spider, response.status)

但这不适用于提交表单。有人知道 'Scrapy-thonic' 在下载器中间件中使用 FormRequest 的方法是什么吗?

我设法通过以下方式解决了这个问题:

from scrapy import FormRequest

class SubmitFormMiddleware:
    def process_response(self, request, response, spider):
        if response.css('form.loginbox').getall():
            post_form_url = response.css('form.loginbox::attr(action)').get()
            form_request_handle = FormRequest(url=response.urljoin(post_form_url),
                                     formdata={'username': 'my_username',
                                               'password': 'my_password',
                                               'data_selection': 'all'
                                               },
                                     method='POST',
                                     dont_filter=True)
            return request.replace(url=form_request_handle.url,
                                     method='POST',
                                     body=form_request_handle.body,
                                     headers=form_request_handle.headers,
                                     dont_filter=True)
        else:
            return response

虽然这行得通,但我仍然很好奇 'scrapy-thonic' 解决中间件提交一个 FormRequest 的方法。