使用scrapy +selenium爬取动态渲染的页面

背景

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

Scrapy

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。其最初是为了 页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。

Scrapy 安装并运行
  1. 安装 通过pip install Scrapy 安装即可, Ubuntu安装需要安装依赖sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zliblg-dev libffi-dev libssl-dev
  2. 创建项目: scrapy startproject project_name
  3. 创建爬虫: 进入项目根目录 scrapy genspider spider_name sprder_domian
  4. 目录介绍
    project_folder -- 项目文件夹名称
    |
    |──project_name -- 该项目的python模块,一般和项目文件夹名称相同
    |  |
    |  |──spider -- 放置spider代码的包,以后所有的爬虫,都存放在这个里面
    |  |
    |  |──items.py -- 用来存放爬虫怕写来的数据的模型
    |  |
    |  |──middlewares.py -- 用来存放各种中间件的文件
    |  |
    |  |──pipelines.py -- 用来对items里面提取的数据做进一步处理,如保存到本地磁盘等
    |  |
    |  |──settings.py -- 本爬虫的一些配置信息(如请求头、多久发送一次请求、ip代理池等)
    |
    |──scrapy.cfg -- 项目的配置文件
Scrapy 框架模块
  1. Scrapy Engine : Scrapy框架的核心,负责在Spider和Item Pipeline、Downloader、Scheduler中间通信、传输数据等。
  2. Spider : 发送需要爬取的链接给引擎,最后引擎把其他模块请求回来的数据再发给爬虫,爬虫就去解析想要的数据。这部分是我们开发者自己写的,因为要爬取哪些链接,页面中的哪些数据是我们需要的,都是由程序员自己决定。
  3. Scheduler : 复制接收引擎发送过来的请求,并按照一定的方式进行排列和整理,负责调度请求的顺序等。
  4. Downloader : 负责接收引擎传过来的下载请求,然后去网络上下载对应的数据在交还给引擎。
  5. tem Pipeline: 负责将Spider(爬虫)传递过来的数据进行保存,具体保存在哪里,因该看开发者自己的需求。
  6. dwnloader Middlewares : 可以扩展下载器和引擎之间通信功能的中间件。
  7. spider Middlewares : 可以扩展引擎和爬虫之间通信功能的中间件。
Scrapy执行流程

Scrapy中的数据流由执行引擎控制,其过程如下:

  1. 引擎从Spiders中获取到最初的要爬取的请求(Requests);
  2. 引擎安排请求(Requests)到调度器中,并向调度器请求下一个要爬取的请求(Requests);
  3. 调度器返回下一个要爬取的请求(Requests)给引擎;
  4. 引擎将上步中得到的请求(Requests)通过下载器中间件(Downloader Middlewares)发送给下载器(Downloader ),这个过程中下载器中间件(Downloader Middlewares)中的process_request()函数会被调用到;
  5. 一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(Downloader Middlewares)发送给引擎,这个过程中下载器中间件(Downloader Middlewares)中的process_response()函数会被调用到;
  6. 引擎从下载器中得到上步中的Response并通过Spider中间件(Spider Middlewares)发送给Spider处理,这个过程中Spider中间件(Spider Middlewares)中的process_spider_input()函数会被调用到;
  7. Spider处理Response并通过Spider中间件(Spider Middlewares)返回爬取到的Item及(跟进的)新的Request给引擎,这个过程中Spider中间件(Spider Middlewares)的process_spider_output()函数会被调用到;
  8. 引擎将上步中Spider处理的其爬取到的Item给Item 管道(Pipeline),将Spider处理的Request发送给调度器,并向调度器请求可能存在的下一个要爬取的请求(Requests);
  9. (从第二步)重复直到调度器中没有更多的请求(Requests)。
Scrapy架构图

使用scrapy +selenium爬取动态渲染的页面_第1张图片

中间件架构

使用scrapy +selenium爬取动态渲染的页面_第2张图片

selenium

Selenium有很多东西,但从本质上讲,它是一个 Web 浏览器自动化工具集,它使用可用的最佳技术远程控制浏览器实例并模拟用户与浏览器的交互。它允许用户模拟最终用户执行的常见活动;在字段中输入文本,选择下拉值和复选框,并单击文档中的链接。它还提供了许多其他控件,例如鼠标移动、任意 JavaScript 执行等等。

selenium
  1. 安装 pip install selenium
  2. 安装必要驱动
驱动安装

使用selenium驱动chrome浏览器需要下载chromedriver,而且chromedriver版本需要与chrome的版本对应,版本错误的话则会运行报错。
使用scrapy +selenium爬取动态渲染的页面_第3张图片

chrome

下载chromedriver可以通过淘宝镜像地址:http://npm.taobao.org/mirrors/chromedriver/ 。最新的镜像与Chrome同名,尽量选择版本相近的避免兼容问题,镜像下notes.txt可查看当前驱动支持的版本。
使用scrapy +selenium爬取动态渲染的页面_第4张图片

其他浏览器驱动

Operahttp://npm.taobao.org/mirrors/operadriver/

IEhttp://selenium-release.storage.googleapis.com/index.html (版本号要与selenium的版本一致,查看安装的selenium版本,可通过pip show selenium)如果没有可能会打不开,可点击下载3.14.0版本的。

Scrapy + selenium 爬取动态渲染的页面

使用requests爬取动态渲染的页面

使用 requests 库爬取页面
使用scrapy +selenium爬取动态渲染的页面_第5张图片
使用scrapy +selenium爬取动态渲染的页面_第6张图片
使用scrapy +selenium爬取动态渲染的页面_第7张图片

可以看到 返回的页面源码中 只有一个天气表格的框架, 没有我们需要的天气信息. 而且出现了被检测的信息. 出现这种情况 是因为

  • 目标网页是动态渲染的页面, 所以我们只能看到天气表格的框架 看不到具体的信息
  • 目标网页检测到selenium 禁止调试
使用scrapy + selenium爬取动态渲染的页面
  1. 开始一个项目
    使用scrapy +selenium爬取动态渲染的页面_第8张图片

  2. 在scrapy 项目中的 middlewares.py 添加我们自己的下载器组件

  3. 设置pipelines. 这里存储爬取的数据, 演示示例我们只保存页面被选然后的源码
    使用scrapy +selenium爬取动态渲染的页面_第9张图片

  4. 在setting中添加我们自己的中间件
    使用scrapy +selenium爬取动态渲染的页面_第10张图片

  5. 开启运行scrapy 后, 爬取的页面会被保存至my.txt中
    使用scrapy +selenium爬取动态渲染的页面_第11张图片

    表格中天气的具体信息已经被渲染
    使用scrapy +selenium爬取动态渲染的页面_第12张图片

总结

在攥写爬虫程序时, 遇到动态渲染的页面我们可以使用Scrapy+Selenium对页面规避反爬策略和爬取页面信息. 虽然webdriver影响到了Scrapy 的运行速度, 我们还可以使用scrapy-redis让我们的爬虫变成分布式以提高效率.

你可能感兴趣的:(python,Spider,python,后端,测试工具)