一,中间件的概念
中间件是 Scrapy 里面的一个核心概念。使用中间件可以在爬虫的请求发起之前或者请 求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫。在 Scrapy 框架中有 两种中间件:爬虫中间件和下载中间件。
一个框架图重点关注数据的流转—每个组件进出的数据都是怎么流通。
对于爬虫而言其实数据主要:
- url-----在scrapy框架里面将来会封装成一个request对象
- item—提取出来的数据
有两个中间件:功能是由经过他的数据所决定的。
换句话说,就是什么数据进过了他,他就可以处理什么数据。
-
下载中间件(downloader middlewares):
有两个数据经过他:
-
一个是马上要被下载器下载的从调度器里面出来的request
-
被下载器下载好的response
-
-
spider中间件:
有两个数据经过:
-
一个是马上要加入调度器的request
-
下载好的response。
-
下载好的response一般都是统一交给spider中对应parse方法来统一处理的。
如果需要对request处理可以在这两个中间件的两个对应方法中处理。
一般选择下载中间件。
对request处理都有哪些?–所以我们可以在下载中间件中做以下功能:
- 使用selenium下载。—自定义下载功能
- 使用代理
- 更改请求头参数。
二,案例
2.1 案例(豆瓣读书)
项目难点:
-
这个项目中有两种请求:selenium和ajax请求
既用到了自定义下载,又用到下载器。—这种情况如何处理。
其中ajax使用下载器下载。
获取ajax参数的初始请求使用selenium。
1、定义中间件的方法
第一步:创建文件
第二步:在文件中写一个类如下:
第三步:在setting.py中配置
具体处理逻辑在process_request方法中处理即可。
2、定义下载中间件方法
有些网站获取必须全部使用selenium的话,建议:使用之前爬虫,不要使用scrapy。
import time
from scrapy.http import HtmlResponse
from selenium import webdriver
#定义一个下载中间件
#1定义一个类
class My_Middle_Download(object):
#从middlerwares.py中复制这个方法(下载前拦截request方法)
def process_request(self, request, spider):
# print(request.url)
flag = request.meta.get('flag')
print(request.url,flag)
#如果flag为none:这条请求就是用selenium下载
if not flag:
print('in middler')
driver = webdriver.Chrome()
driver.get(request.url)
# 等待
time.sleep(2)
html_str = driver.page_source
driver.quit()
# print(html_str)
# with open('index.html','w',encoding='utf-8') as fp:
# fp.write(html_str)
# Must either:
# - return None: continue processing this request继续这个请求:继续让下载器下载(代理,请求头)
# - or return a Response object:自定义下载
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of:过滤这条请求:增量爬虫其中一种
# installed downloader middleware will be called
# body:响应正文
return HtmlResponse(url=request.url, body=html_str, request=request, encoding='utf-8')
return None#如果flag为true,就是用下载下载
3、中间件中process_request方法返回值
# Must either:
# - return None: continue processing this request继续这个请求:继续让下载器下载(代理,请求头)
# - or return a Response object:自定义下载
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of:过滤这条请求:增量爬虫其中一种
# installed downloader middleware will be called
4、scrapy.Request(meta参数)
5、自定setting的配置
第一步:创建setting文件:
第二步:
(在custom_settings.py)
import random
interval = random.randint(0,1)+random.random()
#自定义配置文件
custom_settings = {
#日志的配置
'LOG_FILE ':'douban_spider.log',#日志存储位置
'LOG_ENABLE':True,#是否开启日志
'LOG_ENCODING':'utf-8',
'LOG_LEVEL':'DEBUG',
#下载间隔的控制
'DOWNLOAD_DELAY':interval,
#超市时长
'DOWNLOAD_TIMEOUT':30,
'DEFAULT_REQUEST_HEADERS':{
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
},
'DOWNLOADER_MIDDLEWARES' : {
'douban_read.my_middle.My_Middle_Download': 543,
},
'ITEM_PIPELINES' :{
'douban_read.pipelines.MongoPipeline': 300,
},
#url
'MONGO_URI' :'localhost',
#mongo数据库
'MONGO_DATABASE' : 'douban_read',
}
第三步:
最后只需要在douban_spider.py中提取网页内容即可