scrapy中间件的使用
时间:2023-3-1 18:55 作者:wen 分类: Python
一、scrapy中间件的分类和作用
-
scrapy中间件的分类
根据scrapy运行流程中所在位置不同分为- 下载中间件
- 爬虫中间件
-
scrapy中间件的作用:预处理request和response对象
- 对header以及cookie进行跟换和处理
- 使用代理ip等
- 对请求进行定制化操作
但是scrapy默认的情况下,两种中间件都在middlewares.py一个文件中
爬虫中间件使用方法和下载中间件相同,且功能重复,通常使用下载中间件
二、下载中间件的使用方法:
- 在middlewares.py中定义中间件
- 在中间件类中,重写处理请求或响应的方法
Download Middlewares默认方法:
process_request(self, request, spider):
- 当每个request通过下载中间件时,该方法被调用
- 返回None值:没有return也是返回None,该request对象传递给下载器,或通过引擎传递给其它权重低的process_request方法
- 返回Response对象:不再请求,把response返回给引擎
- 返回Request对象:把request对象通过引擎交给调度器,此时将不通过其它权重低的process_request方法
process_response(self, request, response, spider):
-
当下载器完成http请求,传递响应给引擎的时候调用
-
返回Response:通过引擎交给爬虫处理或交给权重更低的其它下载中间件的process_response方法
-
返回Request对象:通过引擎交给调度器继续请求,此时将不通过其它权重的process_request方法
-
在setting.py中配置开启中间件,权重值越小越优先执行
# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'tencent.middlewares.TencentSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
'tencent.middlewares.TencentDownloaderMiddleware': 543,
}
三、定义实现随机User-Agent的下载中间件
1、在middlewares.py中完善代码
# middlewares.py
# 定义一个中间件
class RandomUserAgent:
def process_request(self, request, spider):
print(request.headers['User-Agent'])
ua = random.choice(USER_AGENT_LIST)
request.headers['User-Agent'] = ua
2、在setting中设置开启自定义的下载中间件,设置方法同管道
# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
'douban.middlewares.DoubanDownloaderMiddleware': 543,
'douban.middlewares.RandomUserAgent': 544,
}
3、在setting中添加UA的列表
# setting.py
USER_AGENT_LIST = [
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:65.0) Gecko/20100101 Firefox/65.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763',
'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
]
四、代理IP的使用
-
思路分析
- 代理添加的位置:request.meta中添加proxy字段
- 获取一个代理IP,赋值给request.meta['proxy']
- 代理池中随机选择代理ip
- 代理IP的webapi发送请求获取一个代理ip
-
具体实现
# middlewares.py
class RandomProxy:
def process_request(self, request, spider):
proxy = random.choice(PROXY_LIST)
print(proxy)
if 'user_passwd' in proxy:
# 对账号密码进行编码
b64_up = base64.b64encode(proxy['user_passwd'].encode())
# 设置认证
request.headers['Proxy-Authorization'] = 'Basic ' + b64_up.decode()
# 设置代理
request.meta['proxy'] = proxy['ip_prot']
else:
# 设置代理
request.meta['proxy'] = proxy['ip_prot']
# setting.py
PROXY_LIST = [
{'ip_prot': "115.218.5.127:9000"},
{'ip_prot': "183.21.81.88:40539"},
]
-
检测代理ip是否可用
在使用代理IP的情况下可以在下载中间件的process_response()方法中处理代理的使用情况,如果该代理ip不能使用可以替换其它代理ip# middlewares.py class RandomProxy: def process_request(self, request, spider): proxy = random.choice(PROXY_LIST) print(proxy) if 'user_passwd' in proxy: # 对账号密码进行编码 b64_up = base64.b64encode(proxy['user_passwd'].encode()) # 设置认证 request.headers['Proxy-Authorization'] = 'Basic ' + b64_up.decode() # 设置代理 request.meta['proxy'] = proxy['ip_prot'] else: # 设置代理 request.meta['proxy'] = proxy['ip_prot'] def process_response(self, request, response, spider): if response.status != 200: request.dont_filter = True # 重新发送的请求对象能够再次进入列队 return request
在setting中开启下载器中间件
五、在中间件中使用selenium
1、完成爬虫代理
# middlewares.py
class Selenium:
def process_request(self, request, spider):
url = request.url
if 'daydata' in url:
driver = webdriver.Chrome()
driver.get(url)
time.sleep(3)
data = driver.page_source
driver.close()
# 创建响应对象
res = HtmlResponse(url=url,body=data,encoding='utf-8',request=request)
return res
标签: 爬虫