11.scrapy框架简介和基础应用

11.scrapy框架简介和基础应用

一、什么是Scrapy???

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍。

    所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。

    对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。

二、Scrapy安装

  Linux:

      pip3 install scrapy

  Windows:

      a. pip3 install wheel

      b. 下载twisted框架,下载与cpython版本对应的版本   http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

      c. 进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl

      d. pip3 install pywin32

      e. pip3 install scrapy

   安装成功之后可以输入可以通过输入scrapy检测是否安装成功,

   注意:

      不管比在任何地方进行安装,都默认是全局安装

     11.scrapy框架简介和基础应用

三、基础使用

  注意:在操作使用scrapy框架的时,所有的执行命令都需要通过cmd命令行去操作

  1. 创建项目: scrapy  startproject  项目名称

    注意:创建项目的时候要切换到创建目录的文件夹下面  

    11.scrapy框架简介和基础应用

 项目目录结构:

    11.scrapy框架简介和基础应用

   spiders      爬虫目录,必须要在这个目录下面,新创建一个爬虫文件(就是一个py文件)   如:创建文件,编写爬虫解析规则
   scrapy.cfg   项目的主配置信息。(真正爬虫相关的配置信息在settings.py文件中)
       注意: 这个文件千万不要去打开,更不要去修改它里面的内容
   items.py     设置数据存储模板,用于结构化数据,如:Django的Model
   middlewares.py  中间件应用
   pipelines    管道,做通信使用,数据持久化处理   
settings.py 配置文件,如:递归的层数、并发数,延迟下载等

  2. 创建爬虫应用程序

    2.1  首先,要进入项目目录

       cd project_name(项目名称)

    2. 2  创建爬虫文件

      scrapy genspider  爬虫文件的名称  爬取网页的起始url 

      列如:scrapy genspider  baidu  www.baidu.com

    11.scrapy框架简介和基础应用

  3. 编写爬虫文件:在步骤2执行完毕,会在项目的spiders目录下面生成一个应用名的py爬虫文件

   源码如下:

  # -*- coding: utf-8 -*-
  import scrapy


  # FirstSpider类名是指定好的,继承了scrapy.Spider父类
  # 进行数据的爬取和解析
  class FirstSpider(scrapy.Spider):
      # 爬虫文件的名称: 根据名称可以定位到当前的爬虫文件
      name = 'first'
      # 允许爬取的域名(如果遇到非该域名的url则爬取不到数据)
      # 通常情况下,我们将这个域名注释掉
      allowed_domains = ['www.baidu.com']
      # 起始爬取的url列表,里面可以有多个url,
      # 通常我们一个爬虫项目中只写一个url
      start_urls = ['http://www.baidu.com/']

      # parse是访问起始URL并获取结果后的回调函数,该函数的response参数就是向起始的
      # url发送请求后,获取的响应对象.该函数返回值必须为可迭代对象或者NUll
      # 简单来说:response就是起始url对应的响应对象
      def parse(self, response):
          print(response)
          # print(response.text) # 获取的是字符串类型的响应内容
          # print(response.body) # 获取的是字节类型的响应内容

  4.设置修改setting.py配置文件相关配置

  修改内容及其结果如下:

    19行: USER_AGENT 默认是注销的更改为如下:

          USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'

          UA反扒机制,进行伪装请求载体身份操作

    20行: ROBOTSTXT_OBEY = False

        默认是true更改为false,可以忽略或者不遵守robots协议

  5. 执行爬虫程序:

      scrapy crawl  爬虫文件名称

         scrapy crawl  爬虫文件名称 --nolog  

      执行爬虫程序的时候,默认是有日志打印,在其后面添加 --nolog表示曲线日志打印

  示例: 将糗百首页中段子的内容和标题进行爬取

  # -*- coding: utf-8 -*-
  import scrapy


  class QiubaidemoSpider(scrapy.Spider):
      name = 'qiubaiDemo'
      # allowed_domains = ['www.xxxx.com']
      start_urls = ['https://www.qiushibaike.com/text/']
      def parse(self, response):
          # xpath为response中的方法,可以将xpath表达式直接作用于该函数中
          div_list = response.xpath('//div[@>)
          # 用于存储解析到的数据
          dic_data = []

          for div in div_list:
              # xpath函数返回的为列表,列表中存放的数据(div)为Selector类型的数据
              # title = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()')[0].extract()
              # content = div.xpath('./a/div/span[1]/text()')[0].extract()
              title = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
              content = div.xpath('./a/div/span[1]/text()').extract_first()

              # 将解析到的数据封装到字典中
              dic = {
                  "title":title,
                  "content":content
              }
              # 将数据储存到dic_data这个列表中
              dic_data.append(dic)
              # 基于终端指令的持久化存储:可以通过终端指令的形式将parse方法的返回值中存储的数据进行本地磁盘的持久化存储
          return dic_data

所用知识点详解:

  1. xpath为response中的方法,可以将xpath表达式直接作用于该函数中

   response.xpath()

     2. xpath函数返回的为列表,列表中存放的数据为Selector类型的数据

   3. 我们解析到的内容被封装在了Selector对象中,需要调用extract()函数将解析的内容从Selecor中取出

     注意:

      extract()  取出的是多个内容值,

        如果Selector对象中只有一个对象值,我们可以通过extract_first()来获取

    示例:

      title = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()')[0].extract()
     title = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
      这两种方法都是取一个值,但建议使用下面这种方法

   4. 储存数据的方法都是一样的

     4.1   先把将解析到的数据封装到字典中

     4.2   创建一个空列表 ,用于储存解析到数据

     4.3   把封装的字典,添加列表中

     4.4    把列表返回,在做持续化存储

  注意: 千万不要忘记配置setting文件