scrapy middlewares.py

1.概念

类似flask的before_request的思想,就是在scrapy的每次request和response前先进行预处理。
在settings.py中配置开启中间件,权重值越小越优先执行

首先在middlewares.py中定义类,类中实现以下两个方法。

1)process_request(self, request, spider):
当每个request通过下载中间件时,该方法被调用。

返回None值:没有return也是返回None,传递给其他权重低的中间件(Downloader Middlewares),最后该request对象传递给下载器(Downloader)
返回Request对象:把request对象通过引擎交给调度器,然后递给下载器(Downloader),此时将不通过其他权重低的中间件(Downloader Middlewares)
返回Response对象:不再请求,把response返回给引擎然后引擎给Spider

2)process_response(self, request, response, spider):
当下载器完成http请求,传递响应给引擎的时候调用
返回Resposne:通过引擎交给爬虫处理或交给权重更低的其他下载中间件的process_response方法
返回Request对象:通过引擎交给调取器继续请求,此时将不通过其他权重低的process_request方法

2.应用

2.1 每次请求自动更换header

1)定义中间件

import random
from xxx.settings import USER_AGENTS_LIST # 从setting中导入定义好的user-agent

class UserAgentMiddleware(object):
    def process_request(self, request, spider): 
        request.headers['User-Agent'] = random.choice(USER_AGENTS_LIST)
        # 不写return

class CheckUA:
    def process_response(self,request,response,spider):
        print(request.headers['User-Agent'])
        return response # 不能少!

2)开启中间件

DOWNLOADER_MIDDLEWARES = {
   'xxx.middlewares.UserAgentMiddleware': 543, # 543是权重值
   'xxx.middlewares.CheckUA': 600, # 先执行543权重的中间件,再执行600的中间件
}

2.2 应用-更换ip

1)定义中间件
免费ip

class ProxyMiddleware(object):
    def process_request(self,request,spider):
        # proxies可以在settings.py中,也可以来源于代理ip的webapi
        # proxy = random.choice(proxies) 

        # 免费的会失效,报 111 connection refused 信息!重找一个代理ip再试
        proxy = 'https://1.71.188.37:3128' 

        request.meta['proxy'] = proxy
        return None # 可以不写return
        
    def process_response(self, request, response, spider):
        if response.status != '200':
            request.dont_filter = True # 重新发送的请求对象能够再次进入队列
            return requst

2)在settings.py中开启该中间件

2.3 应用-结合selenium

1)定义中间件

import time
from selenium import webdriver


def getCookies():
    # 使用selenium模拟登陆,获取并返回cookie
    username = input('输入github账号:')
    password = input('输入github密码:')
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    driver = webdriver.Chrome('/home/worker/Desktop/driver/chromedriver',
                              chrome_options=options)
    driver.get('https://github.com/login')
    time.sleep(1)
    driver.find_element_by_xpath('//*[@id="login_field"]').send_keys(username)
    time.sleep(1)
    driver.find_element_by_xpath('//*[@id="password"]').send_keys(password)
    time.sleep(1)
    driver.find_element_by_xpath('//*[@id="login"]/form/div[3]/input[3]').click()
    time.sleep(2)
    cookies_dict = {cookie['name']: cookie['value'] for cookie in driver.get_cookies()}
    driver.quit()
    return cookies_dict

class LoginDownloaderMiddleware(object):

    def process_request(self, request, spider):
        cookies_dict = getCookies()
        print(cookies_dict)
        request.cookies = cookies_dict # 对请求对象的cookies属性进行替换

2)在settings.py中开启该中间件

3)编写代码

import scrapy

class Login4Spider(scrapy.Spider):
    name = 'login4'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/1596930226'] # 直接对验证的url发送请求

    def parse(self, response):
        with open('check.html', 'w') as f:
            f.write(response.body.decode())

你可能感兴趣的:(scrapy middlewares.py)