Loading...
墨滴

公众号:uncle39py

2022/01/13  阅读:23  主题:默认主题

中间件

上一篇介绍了scrapy框架的整体流程和使用,则scrapy大部分的蛋糕都吃下了,剩下的部分是一些精耕细作的局部介绍。

一、下载中间件的使用

(1)整体介绍

scrapy中有两类中间件:爬虫中间件、下载中间件。其中爬虫中间件的实际应用很少,我们重点来介绍下载中间件。

在scrapy项目新建之初,项目目录下就有一个middlewares.py的文件用于编写中间件。

  • process_request()请求来的时候做拦截,它有三个返回值
    • return none:程序继续往后执行
    • return response对象:不走downloader,直接把响应对象返回给engine,然后给spider做解析
    • return request对象:不走downloader,直接把请求对象返回给engine,然后丢到调度器中排序继续来发请求
    • raise异常:流程转到process_exception方法中处理(常用于拦截不需要下载的url)
  • process_response()downloader处理完,响应回来的时候做拦截,它有两个返回值
    • return response对象:按照正常流程走,经由engine到spider中做解析
    • return request对象:直接把请求对象返回给engine,然后丢到调度器中排序继续来发请求
    • raise异常:流程转到process_exception方法中处理(常用于请求回来的是不需要解析的数据)
  • process_exception():流程到了这里,则会终止当前这条链,然后可以返回request或response对象给engine,engine会自动根据对象的类型来处理这两个对象。

在写完中间件的类后,需要在settings.py中做配置,以下配置后,中间件就生效了

DOWNLOADER_MIDDLEWARES = {
   # 数字代表优先级,数字越小优先级越高
   'cnblogs.middlewares.CnblogsDownloaderMiddleware'543,
}
(2)process_request()拦截能做的事情:更换请求头
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'

settings.py中配置一个USER_AGENT表示客户端的浏览器,如果老是用同一个USER_AGENT去爬,则很容易被识破,所以有了更换请求头的中的USER_AGENT这一说。

from fake_useragent import UserAgent
# 可以随机生成一个USER_AGENT(要先安装这个小工具 pip install fake-useragent)
UserAgent().random

# request.headers是一个Headers对象,继承至字典
print(type(request.headers))
print(request.headers)
from scrapy.http.headers import Headers
# 给USER_AGENT随机换值
request.headers['User-Agent']='UserAgent().random'
(3)process_request()拦截能做的事情:加cookie

假设你你已经搭建好cookie池了:

request.cookies={'username':'asdfasdf'}

(4)process_request()拦截能做的事情:加代理

request.meta["proxy"] = 'http://27.188.62.3:8060'

代理从代理池中取,github上有python写的排名的第一的那个,可以爬取免费可用的代理存放在redis中,用的时候随机取一个。

(5)process_request()拦截能做的事情:集成selenium

在爬虫中初始化浏览器对象,这样只会创建一个浏览器对象,倘若放在中间件中就会出现每一个请求创建一个浏览器对象(内存会被占满)

from selenium import webdriver
class CnblogSpider(scrapy.Spider):
    name = 'cnblog'
    allowed_domains = ['www.cnblogs.com']
    start_urls = ['https:/www.cnblogs.com/']
    bro=webdriver.Chrome(executable_path='../chromedriver.exe')

中间件中使用

from scrapy.http import Response, HtmlResponse

class CnblogsDownloaderMiddleware:
    def process_request(self, request, spider):
        spider.bro.get('https://dig.chouti.com/')
        print(spider.bro.page_source)
        #必须return response对象
        response=HtmlResponse(url='https://dig.chouti.com/',body=spider.bro.page_source.encode('utf-8'),request=request)
        return response

在爬虫中关闭

def close(self, reason):
    self.bro.close()

公众号:uncle39py

2022/01/13  阅读:23  主题:默认主题

作者介绍

公众号:uncle39py