scrapy框架的中间件

中间件的使用

  • 作用:拦截所有的请求和响应
  • 拦截请求:process_request拦截正常的请求,process_exception拦截异常的请求
    • 篡改请求的头信息

      def process_request(self, request, spider):
          print('proces_request!!!')
          #UA伪装
          request.headers['User-Agent'] = random.choice(self.user_agent_list)
          return None
      
      # user_agent_list 这个列表中是大量的浏览器信息为了给User-Agent切换信息
    • 代理
      #拦截发生异常的请求,目的就是为了将异常的请求进行修正,然后将修正之后的正常的请求进行重新发送
      def process_exception(self, request, exception, spider):
          #代理操作
          # request.meta['proxy'] = 'http://ip:port'
          print('i am exception!!!')
          return request

      注意:process_exception,return request的作用是将修正后的请求重新发送

  • 拦截响应 ------ 以爬取网易新闻为例
    • 篡改响应数据

      • 不满足需求的响应数据对应的一定是不满足需求的响应对象
      • 直接更换响应对象
    • 需求:爬取网易新闻中国内,国际,军事,航工,无人机这五个板块下所有的新闻标题和内容
      • 如何通过中间件更换不满足需求的响应对象
      • selenum如何作用到scrapy
    • 分析:每一个板块中显示的新闻标题是动态加载的
    • seleniumscrapy中的编码流程:
      • 实例化浏览器对象:爬虫类中将实例化出来的浏览器作为爬虫类的一个属性属性可以交互给中间件类
      • 编写自动化操作:写在中间件的process_response
      • 关闭浏览器:写在爬虫类的closed(self)方法中
    • 代码实现:

      爬虫文件得到代码:

      # -*- coding: utf-8 -*-
      import scrapy
      from selenium import webdriver
      from wangyiPro.items import WangyiproItem
      class WangyiSpider(scrapy.Spider):
          name = 'wangyi'
          # allowed_domains = ['www.xxx.com']
          start_urls = ['https://news.163.com/']
          #整个项目中涉及的响应对象个数:
              # - 1+5+n
          #解析:解析五个新闻板块对应的url
          five_model_urls = []
          bro = webdriver.Chrome(executable_path=r'C:\Users\Administrator\Desktop\爬虫+数据+算法\chromedriver.exe')
      
          #方法只会被调用一次
          def closed(self,spider):
              self.bro.quit()
      
          def parse(self, response):
              li_list = response.xpath('//*[@id="index2016_wrap"]/div[1]/div[2]/div[2]/div[2]/div[2]/div/ul/li')
              model_indexs = [3,4,6,7,8]
              for index in model_indexs:
                  li_tag = li_list[index]
                  #解析出了每一个板块对应的url
                  model_url = li_tag.xpath('./a/@href').extract_first()
                  self.five_model_urls.append(model_url)
                  #对每一个板块的url进行手动的请求发送
                  yield scrapy.Request(model_url,callback=self.parse_model)
      
          #解析:每一个板块中的新闻标题和新闻详情页的url(两个值都是动态加载出来的)
          def parse_model(self,response):
              #遇到了不满足需求的响应对象就是当前方法中的response参数
              div_list = response.xpath('/html/body/div/div[3]/div[4]/div[1]/div/div/ul/li/div/div')
              for div in div_list:
                  title = div.xpath('./div/div[1]/h3/a/text()').extract_first()
                  detail_url = div.xpath('./div/div[1]/h3/a/@href').extract_first()
                  item = WangyiproItem()
                  item['title'] = title
                  if detail_url:
                      yield scrapy.Request(detail_url,callback=self.parse_detail,meta={'item':item})
      
          def parse_detail(self,response):
              item = response.meta['item']
              content = response.xpath('//*[@id="endText"]//text()').extract()
              content = ''.join(content)
              item['content'] = content
      
              yield item

      items.py文件的代码:

      import scrapy
      
      class WangyiproItem(scrapy.Item):
          # define the fields for your item here like:
          title = scrapy.Field()
          content = scrapy.Field()
      

      middlewares.py文件的代码:中间件

      # -*- coding: utf-8 -*-
      
      # Define here the models for your spider middleware
      #
      # See documentation in:
      # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
      
      from scrapy import signals
      from scrapy.http import HtmlResponse
      from time import sleep
      
      class WangyiproDownloaderMiddleware(object):
      
          def process_request(self, request, spider):
              return None
          #拦截所有的响应(1+5+n),只有5个响应不满足需求
          def process_response(self, request, response, spider):
              #1.将拦截到所有的响应中的指定5个不满足需求的响应对象找出
                  # request.url:每一个响应对应的url
                  #spider.five_model_urls:5个板块对应的url
              # print(spider.five_model_urls)
              if request.url in spider.five_model_urls:
                  #满足if条件的response就是5个板块对应的response
                  spider.bro.get(request.url)#对每一个板块对应的url进行get请求发送
                  sleep(3)
                  spider.bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
                  sleep(2)
                  spider.bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
                  sleep(2)
                  page_text = spider.bro.page_source
                  new_response = HtmlResponse(url=request.url,body=page_text,encoding='utf-8',request=request)
                  return new_response
              #2.将这5个响应对象删除,实例化5个新的响应对象
              #3.保证5个新的响应对象中包含动态加载出来的新闻标题数据
              #4.将满足需求的5个新的响应对象返回
              else:
                  return response
      
          def process_exception(self, request, exception, spider):
      
              pass
      

    ? 注:记得在settings.py文件中开启对应的操作

原文地址:https://www.cnblogs.com/zhufanyu/p/12020527.html

时间: 2024-08-30 17:20:03

scrapy框架的中间件的相关文章

python爬虫Scrapy框架之中间件

Downloader Middleware处理的过程主要在调度器发送requests请求的时候以及网页将response结果返回给spider的时候, 所以说下载中间件是结余Scrapy的request/response处理的钩子, 用于修改Scrapy request和response. 编写自己的下载器中间件 : 编写下载器中间件, 需要定义下一或者多个方法的python类 新建一个关于爬取httpbin.org网站的项目 scrapy startproject httpbintest cd

scrapy框架之下载中间件

介绍 中间件是Scrapy里面的一个核心概念.使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫. “中间件”这个中文名字和前面章节讲到的“中间人”只有一字之差.它们做的事情确实也非常相似.中间件和中间人都能在中途劫持数据,做一些修改再把数据传递出去.不同点在于,中间件是开发者主动加进去的组件,而中间人是被动的,一般是恶意地加进去的环节.中间件主要用来辅助开发,而中间人却多被用来进行数据的窃取.伪造甚至攻击. 在Scrapy中有两种中间件:下载器

scrapy框架【下载中间件】

介绍 中间件是Scrapy里面的一个核心概念.使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫. “中间件”这个中文名字和前面章节讲到的“中间人”只有一字之差.它们做的事情确实也非常相似.中间件和中间人都能在中途劫持数据,做一些修改再把数据传递出去.不同点在于,中间件是开发者主动加进去的组件,而中间人是被动的,一般是恶意地加进去的环节.中间件主要用来辅助开发,而中间人却多被用来进行数据的窃取.伪造甚至攻击. 在Scrapy中有两种中间件:下载器

爬虫5 scrapy框架2 全站爬取cnblogs, scarpy请求传参, 提高爬取效率, 下载中间件, 集成selenium, fake-useragent, 去重源码分析, 布隆过滤器, 分布式爬虫, java等语言概念补充, bilibili爬视频参考

1 全站爬取cnblogs # 1 scrapy startproject cnblogs_crawl # 2 scrapy genspider cnblogs www.cnblogs.com 示例: # cnblogs_crawl/cnblogs_crawl/spiders/cnblogs.py import scrapy from cnblogs_crawl.items import CnblogsCrawlItem from scrapy.http import Request class

Python爬虫从入门到放弃(十一)之 Scrapy框架整体的一个了解

这里是通过爬取伯乐在线的全部文章为例子,让自己先对scrapy进行一个整理的理解 该例子中的详细代码会放到我的github地址:https://github.com/pythonsite/spider/tree/master/jobboleSpider 注:这个文章并不会对详细的用法进行讲解,是为了让对scrapy各个功能有个了解,建立整体的印象. 在学习Scrapy框架之前,我们先通过一个实际的爬虫例子来理解,后面我们会对每个功能进行详细的理解.这里的例子是爬取http://blog.jobb

scrapy框架设置代理

网易音乐在单ip请求下经常会遇到网页返回码503的情况经查询,503为单个ip请求流量超限,猜测是网易音乐的一种反扒方式因原音乐下载程序采用scrapy框架,所以需要在scrapy中通过代理的方式去解决此问题在scrapy中使用代理,有两种使用方式 1.使用中间件2.直接设置Request类的meta参数 下面依次简要说明下如何使用 方式一:使用中间件要进行下面两步操作 在文件 settings.py 中激活代理中间件ProxyMiddleware在文件 middlewares.py 中实现类P

python——Scrapy 框架

爬虫的自我修养_4 一.Scrapy 框架简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便. Scrapy 使用了 Twisted['tw?st?d](其主要对手是Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求. Scrapy架构图(绿线是

Requests爬虫和scrapy框架多线程爬虫

1.基于Requests和BeautifulSoup的单线程爬虫 1.1 BeautifulSoup用法总结 1. find,获取匹配的第一个标签 tag = soup.find('a') print(tag) tag = soup.find(name='a', attrs={'class': 'sister'}, recursive=True, text='Lacie') tag = soup.find(name='a', class_='sister', recursive=True, te

网络爬虫之scrapy框架设置代理

前戏 os.environ()简介 os.environ()可以获取到当前进程的环境变量,注意,是当前进程. 如果我们在一个程序中设置了环境变量,另一个程序是无法获取设置的那个变量的. 环境变量是以一个字典的形式存在的,可以用字典的方法来取值或者设置值. os.environ() key字段详解 windows: os.environ['HOMEPATH']:当前用户主目录. os.environ['TEMP']:临时目录路径. os.environ[PATHEXT']:可执行文件. os.en