类似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方法
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的中间件
}
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中开启该中间件
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())