Skip to content

中间件

  • 中间件是 Scrapy 框架中的一个重要组件,用于在请求和响应处理过程中进行自定义的操作。

常用方法

process_request()

在请求之前执行

  • 如果它返回 None,Scrapy 将继续处理此请求,执行所有其他中间件,直到最终调用相应的下载器处理程序来执行请求(并下载其响应)。
  • 如果它返回一个 Response 对象,Scrapy 将不再调用 任何 其他 process_request() 或 process_exception() 方法,也不会调用相应的下载函数;它将直接返回该响应。已安装中间件的 process_response() 方法始终会在每个响应上被调用。
  • 如果它返回一个 Request 对象,Scrapy 将停止调用 process_request() 方法并重新调度返回的请求。一旦新的请求被执行,相应的中间件链将对下载的响应进行调用。
  • 如果它抛出 IgnoreRequest 异常,则将调用已安装下载器中间件的 process_exception() 方法。如果没有中间件处理该异常,则会调用请求的 errback 函数(Request.errback)。如果没有代码处理抛出的异常,它将被忽略且不记录日志(与其他异常不同)。

process_response()

在请求之后执行

  • 如果它返回一个 Response 对象(可以是给定的同一个响应,也可以是一个全新的响应),该响应将继续由链中下一个中间件的 process_response() 方法处理。
  • 如果它返回一个 Request 对象,中间件链将中止,并且返回的请求将被重新调度以便将来下载。这与 process_request() 返回请求时的行为相同。
  • 如果它抛出 IgnoreRequest 异常,则会调用请求的 errback 函数(Request.errback)。如果没有代码处理抛出的异常,它将被忽略且不记录日志(与其他异常不同)。

常用中间件

随机User-Agent中间件

  • middlewares.py中添加代码
python
class RandomUserAgentMiddleware:
    def process_request(self, request, spider):
        agent_list = [
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58",
        ]
        user_agent = random.choice(agent_list)
        request.headers["User-Agent"] = user_agent

随机Proxy中间件

  • middlewares.py中添加代码
python
class RandomProxyMiddleware:
    def process_request(self, request, spider):
        proxy_list = [
            "http://127.0.0.1:8888",
            "http://127.0.0.1:8889",
        ]
        proxy = random.choice(proxy_list)
        request.meta["proxy"] = proxy

selenium中间件

  • middlewares.py中添加代码
python
from scrapy.http import HtmlResponse
from selenium import webdriver
class SeleniumMiddleware:
	def process_request(self, request, spider):
		if spider.name == "test":
			# 实例化一个浏览器对象
			browser = webdriver.Chrome()
			# 打开url
			browser.get(request.url)
			# 等待页面加载完成
			browser.implicitly_wait(10)
			# 获取页面源码
			page_source = browser.page_source
			# 关闭浏览器
			browser.close()
			# 把页面源码封装到response对象中
			response = HtmlResponse(url = request.url, body = page_source, encoding = "utf-8")
			# 返回response对象
			return response

使用方法

settings.py中配置中间件,数字越小,优先级越高

json
DOWNLOADER_MIDDLEWARES = {
    "my_spider.middlewares.MySpiderMiddleware": 543,
}