一. 引入

  在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值。但是通过观察我们会发现,通过浏览器进行url请求发送则会加载出对应的动态加载出的数据。那么如果我们想要在scrapy也获取动态加载出的数据,则必须使用selenium创建浏览器对象,然后通过该浏览器对象进行请求发送,获取动态加载的数据值。

二. 今日详情

1.案例分析:

(1).需求: 爬取网易新闻的国内板块下的新闻数据

(2).需求分析: 当点击国内超链接进入国内对应的页面时, 会发现当前页面展示的新闻数据是被动态加载出来的, 如果直接通过程序对url进行请求, 是获取不到动态加载出的新闻数据的, 则就需要我们使用selenium实例化一个浏览器对象, 在该对象中进行url请求, 获取动态加载的新闻数据

2. selenium在scrapy中使用的原理分析:

  当引擎将国内板块url对应的请求提交给下载器后,下载器进行网页数据的下载,然后将下载到的页面数据,封装到response中,提交给引擎,引擎将response在转交给Spiders。Spiders接受到的response对象中存储的页面数据里是没有动态加载的新闻数据的。要想获取动态加载的新闻数据,则需要在下载中间件中对下载器提交给引擎的response响应对象进行拦截,切对其内部存储的页面数据进行篡改,修改成携带了动态加载出的新闻数据,然后将被篡改的response对象最终交给Spiders进行解析操作。

3. selenium在scrapy中的使用流程:

  • 重写爬虫文件的构造方法,在该方法中使用selenium实例化一个浏览器对象(因为浏览器对象只需要被实例化一次)
  • 重写爬虫文件的closed(self,spider)方法,在其内部关闭浏览器对象。该方法是在爬虫结束时被调用
  • 重写下载中间件的process_response方法,让该方法对响应对象进行拦截,并篡改response中存储的页面数据
  • 在配置文件中开启下载中间件

4. 代码展示:

  爬虫文件代码:

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from Wangyixinwen.items import WangyixinwenItem
  4. from selenium import webdriver
  5.  
  6. class WangyiSpider(scrapy.Spider):
  7. name = 'wangyi'
  8. # allowed_domains = ['www.xxx.com']
  9. #自动发送请求的 去设置里将user-agent以及robots协议设置好
  10. start_urls = ['https://news.163.com/']
  11. """"
  12. 我们的第一次请求对象就是start_urls开始,我们还需要对UA伪装同时还有IP代理等,可以在下载中间件的process_request中设置UA伪装
  13. process_exception中设置代理ip(等到自己ip出问题了就用代理ip)。等到响应对象缺失就可以在process_response中拦截。
  14. """
  15. bro = webdriver.Chrome("./chromedriver.exe")
  16. urls = []
  17. def parse(self, response):
  18. #从响应对象中获取到全部目标
  19. target_list = response.xpath('//*[@id="js_festival_wrap"]/div[3]/div[2]/div[2]/div[2]/div/ul/li')
  20. #遍历目标得到具体的url
  21. for index in [3,6,7,8]:
  22. target = target_list[index]
  23. #得到目标的url 并且取出url
  24. target_url = target.xpath('./a/@href').extract_first()
  25. self.urls.append(target_url)
  26. #对目标url发起请求
  27. yield scrapy.Request(url=target_url,callback=self.parse_target)
  28. def parse_target(self,response):
  29. #将第二次请求的响应对象开始解析,分析由于还未编写代码就知道这次是含有动态加载数据,因此这次
  30. #分析可以用到selenium一起解析数据,下面解析出新闻标题以及具体的详情页的url(响应的数据缺失,因此我们需要去下载中间件设置)
  31. detail_list = response.xpath('/html/body/div[1]/div[3]/div[4]/div[1]/div/div/ul/li/div/div')
  32. for detail in detail_list:
  33. title = detail.xpath('./div/div[1]/h3/a/text()').extract_first()
  34. detail_url = detail.xpath('./div/div[1]/h3/a/@href').extract_first()
  35. #实例化item对象,封装数据
  36. item = WangyixinwenItem()
  37. item["title"] = title
  38. yield scrapy.Request(url=detail_url,callback=self.parse_detail,meta={"item":item})
  39. def parse_detail(self,response):
  40. item = response.meta['item']
  41. content = response.xpath('//*[@id="endText"]/p/text()').extract()
  42. #将内容转换为字符串对象
  43. content = "".join(content)
  44. item["content"] = content
  45. #提交数据
  46. yield item
  47. def close(self,spider):
  48. # 爬虫结束,浏览器也关闭
  49. print("爬虫结束!!!")
  50. self.bro.quit()

 中间件文件拦截代码展示:

  1. # -*- coding: utf-8 -*-
  2.  
  3. # Define here the models for your spider middleware
  4. #
  5. # See documentation in:
  6. # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
  7.  
  8. from scrapy import signals
  9. from scrapy.http import HtmlResponse
  10. import random
  11. from time import sleep
  12.  
  13. class WangyixinwenDownloaderMiddleware(object):
  14. # Not all methods need to be defined. If a method is not defined,
  15. # scrapy acts as if the downloader middleware does not modify the
  16. # passed objects.
  17.  
  18. def process_request(self, request, spider):
  19.  
  20. return None
  21.  
  22. def process_response(self, request, response, spider):
  23. #刚才响应体缺失,因此从这里我们应该重新返回新的响应体
  24. #这里要用到爬虫程序中的urls,判断url是否在里面,在urls里面的就会出现响应缺失,
  25. # 、因此需要返回新的响应体
  26. if request.url in spider.urls:
  27. #响应缺失是因为是动态加载数据,因此我们配合selenium使用
  28. #在这里实例化selenium的话会被实例化多次,然而selenium只需要实例化一次,
  29. #这个时候我们可以将selenium放在实例化一次的爬虫程序开始的时候,实例化完成引入
  30. sleep(2)
  31. bro = spider.bro.get(url=request.url)#浏览器中发送请求
  32. sleep(1)
  33. spider.bro.execute_script("window.scrollTo(0,document.body.scrollHeight)")
  34. sleep(1.5)
  35. spider.bro.execute_script("window.scrollTo(0,document.body.scrollHeight)")
  36. sleep(0.7)
  37. spider.bro.execute_script("window.scrollTo(0,document.body.scrollHeight)")
  38. sleep(1)
  39. spider.bro.execute_script("window.scrollTo(0,document.body.scrollHeight)")
  40. #发送到请求我们需要获取浏览器当前页面的源码数据 获取数据之前需要翻滚页面
  41. page_text = spider.bro.page_source
  42. #改动返回响应对象 scrapy提供了一个库url=spider.bro.current_url, body=page_text, encoding='utf-8', request=request
  43. new_response = HtmlResponse(url=request.url,body=page_text,encoding="utf-8",request=request)
  44. return new_response
  45. else:
  46. return response
  47. #提交完新的响应体之后,去设置将下载中间件打开
  48.  
  49. def process_exception(self, request, exception, spider):
  50. pass

备注:仔细看代码注释,能够迅速唤醒记忆,更快开发。

13-scrapy中selenium的应用的更多相关文章

  1. 15.scrapy中selenium的应用

    引入 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值.但是通过观察我们会发现 ...

  2. scrapy中selenium的应用

    引入 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值.但是通过观察我们会发现 ...

  3. scrapy中 selenium(中间件) + 语言处理 +mysql

    在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值.但是通过观察我们会发现,通过 ...

  4. 15,scrapy中selenium的应用

    引入 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生如果直接用scrapy对其url发请求,是获取不到那部分动态加载出来的数据值,但是通过观察会发现,通过浏览器 ...

  5. 14 Scrapy中selenium的应用

    在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值.但是通过观察我们会发现,通过 ...

  6. selenium在scrapy中的使用、UA池、IP池的构建

    selenium在scrapy中的使用流程 重写爬虫文件的构造方法__init__,在该方法中使用selenium实例化一个浏览器对象(因为浏览器对象只需要被实例化一次). 重写爬虫文件的closed ...

  7. Scrapy中集成selenium

    面对众多动态网站比如说淘宝等,一般情况下用selenium最好 那么如何集成selenium到scrapy中呢? 因为每一次request的请求都要经过中间件,所以写在中间件中最为合适 from se ...

  8. 在Scrapy中使用selenium

    在scrapy中使用selenium 在scrapy中需要获取动态加载的数据的时候,可以在下载中间件中使用selenium 编码步骤: 在爬虫文件中导入webdrvier类 在爬虫文件的爬虫类的构造方 ...

  9. selenium在scrapy中的应用

    引入 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值.但是通过观察我们会发现 ...

  10. 第三百五十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—将selenium操作谷歌浏览器集成到scrapy中

    第三百五十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—将selenium操作谷歌浏览器集成到scrapy中 1.爬虫文件 dispatcher.connect()信号分发器,第一个参数信 ...

随机推荐

  1. Creating a Physical Standby from Primary on Version 12c (Doc ID 1570958.1)

    Creating a Physical Standby from Primary on Version 12c (Doc ID 1570958.1) APPLIES TO: Oracle Databa ...

  2. 浅谈C++ STL string容器

    浅谈C++ STL string容器 本篇随笔简单讲解一下\(C++STL\)中\(string\)容器的使用方法及技巧. string容器的概念 其实\(string\)并不是\(STL\)的一种容 ...

  3. 性能分析-java程序篇之案例-工具和方法

    1. 背景说明 线上服务响应时间超过40秒,登录服务器发现cpu将近100%了(如下图),针对此问题,本文说明排查过程.工具以定位具体的原因. 2. 分析排查过程 此类问题的排查,有两款神器可用,分别 ...

  4. Python 从入门到进阶之路(四)

    之前的文章我们简单介绍了一下 Python 的几种变量类型,本篇文章我们来看一下 Python 中的函数. 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性, ...

  5. 【带着canvas去流浪(9)】粒子动画

    目录 一. 粒子特效 二. 开发中遇到的问题 2.1 卡顿 2.2 轨迹 2.3 复位 2.4 防护层 2.5 二维向量类 三. 实现讲解 3.1 粒子类的update方法 3.2 粒子群的绘制 3. ...

  6. Redis 数据类型及应用场景

    一. redis 特点 所有数据存储在内存中,高速读写 提供丰富多样的数据类型:string. hash. set. sorted set.bitmap.hyperloglog 提供了 AOF 和 R ...

  7. js获取时间,循环执行任务,延迟执行任务

    一.获取时间 核心方法创建一个时间对象:new Date() 时间对象相关操作 时间对象.函数名 函数名 功能 getYear() 获取四位数的年份 getMonth() 获取2位数的月数, 这个是从 ...

  8. 本地SQL Server数据库提示网络问题无法连接

    运行程序时发现本地SQLserver数据库无法连接,提示信息为:在与SQL Server 建立连接时出现与网络相关的或特定与实例的错误.未能找到或无法访问服务器.请验证实例名称是否正确并且SQL Se ...

  9. Winform中在使用VS+svn进行协同开发时添加引用时的相对路径和绝对路径的问题

    场景 使用Visual Studio 开发Winform程序,使用SVN进行项目版本管理. 在添加引用时,会出现在A电脑中添加了绝对路径的引用,在B电脑中就会出现找不到 并且将此引用标识为?的状态. ...

  10. Ext.ux.UploadDialog上传大文件 HTTP 错误 413.1 - Request Entity Too Large Web 服务器拒绝为请求提供服务,因为该请求实体过大。Web 服务器无法为请求提供服务,因为它正尝试与客户证书进行协商,但请求实体过大。

    问题描述 问题:HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求. 原因:Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值(I ...