scrapy爬虫概述

    科技2022-07-17  109

    - 创建一个工程 - scrapy startproject proName - 工程目录下的两个文件表示的含义: - spiders包:爬虫文件夹 - 必须在爬虫文件夹中创建一个爬虫源文件 - settings.py:配置文件 - cd proName - 创建一个爬虫文件(爬虫文件要创建在spiders包中) - scrapy genspider spiderName www.xxx.com - 爬虫文件可以使用上述指令创建多个 - 编写爬虫文件 - 执行工程 - scrapy crawl spiderName

    爬虫文件的编写 - 定义好了一个类,该类的父类是Spider,Spider是scrapy所有类的父类 - 类中定义好了三个属性和一个方法 - name:爬虫文件的名称 - start_urls:起始url列表 - 作用:可以对列表中的url进行get请求的发送 - allow_demains:允许的域名。 - parse(self,response): - 将起始url列表中的url请求成功后,response就是获取的响应对象, 在该方法中负责实现数据解析 - scrapy工程默认是遵从rotbos协议的,需要在配置文件中进行操作: - 不遵从robots协议 - 指定日志等级 - LOG_LEVEL = ‘ERROR’

    数据解析 - response.xpath() - 注意:提取标签内容时,返回的不是字符串,而是Selector对象,字符串是存储在该对象中的。 需要调用extract()或者extract_first()将Selector对象中的字符串取出。

    持久化存储 - 基于终端指令: - 只可以将parse方法的返回值存储写入到指定后缀的文本文件中。 - 通过指定方式执行工程: - scrapy crawl duanzi -o data_duanzi.csv

    - 基于管道: - 实现流程: - 1.在爬虫文件中解析数据 - 2.在Item类中定义相关的属性(解析的数据有几个字段就定义几个属性) - 3.将在爬虫文件中解析的数据存储封装到Item对象中 - 4.将存储了解析数据的Item对象提交给管道 - 5.在管道文件中接受Item对象,且对其进行任意形式的持久化存储操作 - 6.在配置文件中开启管道 - 如何实现数据的备份 - 指的是将爬取到的一组数据存储到多个不同的载体(文件,mysql,redis)中。 - 持久化存储的操作必须要写在管道文件中 - 一个管道类对应一种形式的持久化存储 - 如果想将数据存储到多个载体中则必须要有多个管道类 - 问题:让两个管道类都接受到item且对其进行持久化存储,爬虫文件提交的item可以同时提交给 两个管道类? - 爬虫文件提交的item只可以提交个优先级最高的那一个管道类。 - 如何可以让优先级低的管道类也可以获取接受到item呢? - 可以让优先级高的管道类在process_item中通过return item的形式将item 传递给下一个即将被执行的管道类。

    手动请求发送实现的全站数据爬取 - 如何通过代码手动对指定的url进行请求发送 - yield scrapy.Request(url,callback):get请求 - 如何手动发起post请求 - yield scrapy.FormRequest(url,formdata,callback) - 注意:在scrapy中一般不发送post请求

    请求传参

    作用:实现深度爬取。深度爬取:你爬取的数据没有存在于同一张页面中。实现: yield scrapy.Request(url,callback,meta={xxx:xxx}) 可以将meta字典传递给callback callback接受meta: meta = response.meta

    五大核心组件 引擎(Scrapy) 用来处理整个系统的数据流处理, 触发事务(框架核心) 调度器(Scheduler) 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址 下载器(Downloader) 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的) 爬虫(Spiders) 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面 项目管道(Pipeline) 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

    scrapy配置文件settings.py其他配置 增加并发: 默认scrapy开启的并发线程为16个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。

    降低日志级别: 在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘ERROR’

    禁止cookie: 如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False

    禁止重试: 对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False

    减少下载超时: 如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s

    中间件

    下载中间件(讲解)

    爬虫中间件

    作用:

    下载中间件是处于引擎和下载器之间。批量拦截请求和响应。

    拦截请求

    请求头的伪装:

    process_reqeust: request.headers[‘xxxx’] = ‘xxx’

    代理

    process_exception: request.meta[‘proxy’] = ‘http://ip:port’

    process_request:每次发起请求,请求都会被该方法拦截到

    process_response:只要返回一个响应,就会被该方法拦截到

    process_Exception:只要有异常的请求,就会被该方法拦截到,该方法负责对异常的请求 进行修正,且使用return request将修正后的请求对象进行重新方法。

    拦截响应

    篡改响应数据(自学)

    CrawlSpider

    是Spider的一个子类。之前创建的爬虫文件的爬虫类的父类就是Spider

    作用:用于实现全站数据爬取

    使用:

    创建工程cd 工程目录创建爬虫文件: scrapy genspider -t crawl spiderName www.xxx.com 执行工程

    链接提取器,规则解析器这两个工程是crawlSpider独有的。

    链接提取器LinkExtractor

    作用:根据指定的规则进行连接(url)的提取

    规则解析器Rule

    注意:

    1.一个链接提取器对应一个规则解析器2.可以有多个链接提取器和规则解析器3.使用CrawlSPider实现深度爬取的话,最好结合着手动请求发送一起使用4.如何使用CrawlSPider将一个网站中所有的链接捕获到? LinkExtract(allow=r’’)

    follow=True:

    让链接提取器 继续作用到 链接提取器提取到的链接 所对应的页面中

    分布式

    概念:使用多台机器搭建一个分布式机群,在分布式机群中共同运行同一组程序,让其 对同一个网络资源进行联合数据爬取。

    原生的scrapy框架是无法实现分布式?

    调度器无法被分布式机群共享管道无法被共享

    如何实现分布式?

    使用scrapy结合着scrapy-redis组件实现分布式

    scrapy-redis组件作用:

    给scrapy提供可以被共享的管道和调度器pip install scrapy_redis

    实现流程: 1.创建工程 2.cd 工程 3.创建爬虫文件: - 基于CrawlSpider的爬虫文件 4.修改爬虫文件 - 导包:from scrapy_redis.spiders import RedisCrawlSpider - 修改当前爬虫类的父类: - RedisCrawlSpider - 删除start_urls,添加一个新属性: - redis_key = ‘xxx’,可以被共享的调度器队列的名称 - 基于常规的操作获取url发送请求解析数据 5.修改配置文件:settings - 指定调度器: # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化 DUPEFILTER_CLASS = “scrapy_redis.dupefilter.RFPDupeFilter” # 使用scrapy-redis组件自己的调度器 SCHEDULER = “scrapy_redis.scheduler.Scheduler” # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据 SCHEDULER_PERSIST = True - 指定管道: ITEM_PIPELINES = { ‘scrapy_redis.pipelines.RedisPipeline’: 400 }

    - 指定redis服务器: REDIS_HOST = 'redis服务的ip地址' REDIS_PORT = 6379

    6.对redis的配置文件进行配置(redis.windows.conf) - 取消默认绑定 - 将bind 127.0.0.1进行注释 - 关闭保护模式 - protected-mode yes:将yes改为no 7.启动redis的服务器和客户端 - redis服务端的启动: - 在终端里执行:redis-server.exe redis.windows.conf - 启动客户端:redis-cli

    8.执行分布式程序 - 在日志输出可以看出日志hang住了,为啥会hang住,因为在等待起始的url 9.向调度器的队列中扔入一个起始的url: - 在redis-cli:lpush sunQueue http://wz.sun0769.com/index.php/question/questionType?type=4&page= 10.redis-cli: - proName:items命名的数据结构中

    增量式:

    概念:监测网站数据更新情况,爬取最新更新出来的数据

    去重

    实现增量:

    对爬取的url进行检测,使用一个记录表存储爬取过的数据的url,但凡记录表中存有的url说明url对应数据爬取过了,否则表示没有爬取为新数据

    记录表:

    redis的set集合充当记录表
    Processed: 0.010, SQL: 8