Scrapy 中如何实现请求和响应的拦截和修改?

2023-04-17 00:00:00 拦截 求和 如何实现

在 Scrapy 中,可以通过编写中间件(Middleware)来实现请求和响应的拦截和修改。中间件是 Scrapy 处理请求和响应的机制,它可以在请求和响应被 Scrapy 发送和返回之前或之后进行额外的操作。

下面是中间件的主要方法和作用:

  1. process_request(self, request, spider):
    这个方法会在每个请求被发出前调用,可以在这里对请求进行修改或拦截。例如可以修改请求的 URL 或添加请求头:
class MyMiddleware(object):
    def process_request(self, request, spider):
        request.url = 'pidancode.com'
        request.headers['User-Agent'] = 'My User Agent'
  1. process_response(self, request, response, spider):
    这个方法会在每个响应被返回后调用,可以在这里对响应进行修改或拦截。例如可以修改响应内容或对特定状态码进行处理:
class MyMiddleware(object):
    def process_response(self, request, response, spider):
        if response.status == 404:
            new_response = HtmlResponse(url='http://pidancode.com', ...)
            return new_response
        else:
            return response
  1. process_exception(self, request, exception, spider):
    这个方法会在请求处理出错时调用,可以在这里对异常进行处理或者重新发起请求:
class MyMiddleware(object):
    def process_exception(self, request, exception, spider):
        if isinstance(exception, HttpError):
            new_request = request.copy()
            new_request.url = 'http://pidancode.com'
            return new_request

在 Scrapy 中使用中间件是通过在 settings.py 文件中设置 DOWNLOADER_MIDDLEWARES 配置项来实现的。下面是一个范例:

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.MyMiddleware': 543,
}

其中,myproject.middlewares.MyMiddleware 是中间件类的路径,543 是中间件的优先级,数字越小越优先。

对于添加请求头的范例,代码如下:

from scrapy import Selector
from scrapy.http import HtmlResponse

class MyMiddleware(object):
    def process_request(self, request, spider):
        request.headers['User-Agent'] = 'My User Agent'

    def process_response(self, request, response, spider):
        if 'pidancode.com' in response.url:
            sel = Selector(text=response.text.replace('pidancode.com', '皮蛋编程'))
            new_response = HtmlResponse(url=response.url,
                                        body=sel.extract(),
                                        encoding='utf-8',
                                        request=request)
            return new_response
        else:
            return response

这个中间件会将请求头中的 User-Agent 修改为 'My User Agent',并且将响应中的 'pidancode.com' 文本替换为 '皮蛋编程'。

相关文章