一、Scrapy框架

1. Scrapy框架主要组成

a. Scrapy三个对象: request请求对象、response响应对象、item数据对象(字典)

b. Scrapy五个核心组件:
Spider爬虫组件、构建爬虫的起始请求并交给调度器, 解析响应提取数据,交给管道保存。
Engine引擎组件、调用各个组件执行功能,并接收返回值和传递参数
Scheduler调度器、调度器请求去重并临时存储请求,交给下载器发送请求
Downloader下载器、下载发送请求,返回响应交给爬虫解析
Pipeline管道、保存数据

c. Scrapy两个可选中间件:
DownloaderMiddlewaresSpider下载中间件、处理反爬相关操作
SpiderMiddlewaresSpider中间件、请求交给调度器之前的特殊处理。

d. Scrapy框架流程: 爬虫组件 -> 引擎组件 -> 调度器 -> 引擎组件 -> 下载器 -> 引擎组件 -> 爬虫组件
若下载器返回的是请求时: -> 引擎组件 -> 调度器 -> 引擎组件 -> 下载器 -> 引擎组件 -> 爬虫组件
若下载器返回的是item对象: -> 引擎组件 -> 管道

补充:
Spider爬虫组件构建起始请求的url、xpath解析提取响应对象的数据
Scheduler调度器所有请求完毕Spider就会终止
组件之间存在数据交互,可使用中间件进行外部扩展

2. 拟人化流程

1> 引擎 :Hi! Spider , 老大要处理哪⼀个⽹站?把第⼀批需要处理的URL请求给我吧。
2> Spider :给你,第⼀批URL "http://www.baidu.com/"

3> 引擎 :Hi! 调度器 ,我这有request请求你帮我去重⼊队⼀下。
4> 调度器 :正在处理你等⼀下...好的,处理好了。
5> 引擎 :Hi! 调度器 ,把你去重好的request请求给我。
6> 调度器 :给你,这是我去重好的request

7> 引擎 :Hi!下载器,你按照⽼⼤的 下载中间件 的设置帮我下载⼀下这个request请求,
8> 下载器 :稍等... 行了给你,这是下载好的响应。
(如果失败:sorry,这个请求下载失败了。然后 引擎 告诉 调度器 : 这个request下载失败了,你放到请求队列里,我待会⼉再找你要重新下载。)

9> 引擎 :Hi! Spider ,这是下载好的响应,并且已经按照⽼⼤的 下载中间件 处理过了,你⾃⼰处理⼀下。
10> Spider :引擎 ,我这⾥有两个处理结果,这个是我需要跟进的URL请求,还有这个是我获取到的Item数据。

11> 引擎 :Hi ! 管道 我这⼉有个item数据你帮我保存⼀下。 调度器,这是需要跟进URL请求你帮我处理下,然后从我们第五步开始循环,直到获取完⽼⼤需要全部信息。

12> 管道+调度器 :好的,现在就做!

注意:只有当 调度器 没有request需要处理时,整个程序才会停⽌。(对于下载失败的请求,Scrapy也会重新下载。总共3次。)
框架默认的请求重试的时间是180s,可改变setting文件的 DOWNLOAD_TIMEOUT 变量的值

3. requests模块&Scrapy框架对比

requests模块的response
import reqeusts
response = reqeusts.get()
response.text # 返回 Unicode字符串
response.content # 网页原始编码字符串,也可以处理图片音视频

Scrapy框架的response
response.text # Unicode字符串
response.body # 网页原始编码字符串,也可以处理图片音视频

requests模块的xpath方法,返回的是已匹配到的 Unicode字符串
# 返回所有xpath匹配对象的列表
rsponse.xpath("//title/text()")

Scrapy框架的xpath方法,返回的是已匹配到对象的列表,Unicode字符串
# 取多值: 返回所有匹配结果的 字符串 列表(如果匹配成功,通过下标获取数据;如果匹配失败,返回空列表,下标获取数据抛异常)
rsponse.xpath("//title/text()").extract()
["", "", ""]

# 取单值:返回第一条符合匹配的字符串(如果匹配成功,返回字符串,如果匹配失败,返回 None)
rsponse.xpath("//title/text()").extract_first()

Scrapy框架支持大量的请求和高并发
Scrapy框架 : 发送请求、解析响应、并发处理、数据存储、请求去重(指纹-url、method、body=sha1字符串)、scrapy_redis支持分布式采集。

4. Scrapy使用的标准流程:

1> 新建项目
scrapy startproject Baidu

2> 进入项目代码,新建 item字段(编写items.py文件)

3> 新建爬虫
scrapy genspider baidu baidu.com

4> 编写爬虫代码(编写 baidu.py),提取数据:URL/item (如果是url则构建请求继续发送,如果是item则交给管道保存)

5> 编写pipeline.py文件

6> 更改settings.py的配置信息(并发量、User-Agent、启用管道)

7> 执行爬虫:
# 查看当前项目下的所有爬虫名
scrapy list
# 运行当前项目下的 指定爬虫(根据爬虫名执行)
scrapy crawl baidu
# 运行当前项目下的 指定爬虫(根据爬虫文件名执行)
#scrapy runspider baidu.py

传统开发:半年 ~ 1年, 所有功能开发完毕后再上线
敏捷开发:快速迭代更新, 先实现一部分功能就上线, 后期再持续更新迭代

5. Scrapy命令行:

scrapy bench:程序启动前组件的加载信息,爬虫运行时的采集信息,爬虫结束后的统计信息
scrapy startproject:创建一个新项目,外层是项目目录,内层有一个同名的代码目录
scrapy genspider:创建一个新爬虫,一个项目可有多个爬虫,scrapy genspider 爬虫名 爬虫可爬虫的域名,爬虫名不能和爬虫名同名
scrapy runspider:在创建项目的地方 运行爬虫 scrapy runspider 爬虫文件名
scrapy shell:以交互模式运行爬虫
scrapy view:在浏览器打开项目
scrapy list:查看爬虫名

scrapy crawl 爬虫名 -o 存储文件名:命令行保存数据
保存文件格式: json(有中括号)、jl(无中括号,按行存储)、xml、csv, 若需存储到数据库时,需要在管道文件中进行编写,并且在setting文件中启用管道

管道文件:
爬虫开启时,调用一次open_spider方法
爬虫运行时,每传递一个item就会调用一次process_item方法
爬虫关闭时,调用一次close_spider方法

6. setting.py文件:

BOT_NAME: 项目名
ROBOTSTXT_OBEY: 是否遵循robot协议,默认True遵循
CONCURRENT_REQUESTS: 最大请求并发量(主要用于指定下载器)
DOWNLOAD_DELAY: 下载延时,每一批请求的等待时间
CONCURRENT_REQUESTS_PER_DOMAIN: 根据特定域名定义并发量
CONCURRENT_REQUESTS_PER_IP: 据特定IP定义并发量
COOKIES_ENDBLED: 是否启用cookie,默认开启
DEFAULT_REQUEST_HEADERS: 默认的请求报头

**中间件都遵循:值越小优先级越高,值的范围 0-1000**
SPIDER_MIDDLEWARES: 爬虫中间件,值越小,优先级越高
DOWNLOADER_MIDDLEWARES: 下载中间件
ITEM_PIPELINES: 管道中间件
自定义的中间件需添加到setting文件中: 项目名.模块名.中间件类名

7. python补充知识点

锚点: 记录用户从何而来,url路径上的 #

生成器中 yield 作用:
通过yield返回数据,记录方法的状态
通过yield返回不同类型的数据
降低内存占用

python出现异常的方式:
代码错误
手动抛出异常, raise NameError("xxxx")
断言抛出异常,assert 布尔值

控制url查询字符串页码参数的自增量,json文件
提取'下一页按钮的链接',HTML文件
有固定的url地址,可将所有需要请求的url全部保存至start_url中,高并发

python2导入同级目录下的模块无需 . python3导入同级目录下的模块需要加上 .
实现 Python2 & python3 兼容的方法:
try:
from queue import Queue as SameName
except:
from Queue import Queue as SameName

from six.moves.queue import Queue

python有小到大组成: 函数 - 类 - 模块 - 包 - 类库 - 框架
meta字典作为response的属性,进行传递给下一个回调函数

进程、线程、协程:

IO密集(读写网络、磁盘、数据库等):使用多线程,因为io阻塞时,解释器会自动释放GIL尝试让其他线程工作。

互斥锁:一种让多个线程安全、有序的访问内存空间的机制。
GIL:从根本上杜绝了多个线程访问内存空间的安全隐患。

CPU密集(并行计算): 使用多进程,因为不需要切换任务,所以可以充分利用CPU的计算性能。

协程+猴子补丁(处理网络IO密集任务): 猴子补丁可以让Python底层的网络库在处理网络任务时,按异步的方式执行。

并行、并发、同步、异步、阻塞、非阻塞、多线程、多进程、协程、GIL

若方法中没有返回值,返回的None
多进程:并行 适用于CPU计算密集(并行计算)
多线程:并发,适用于io密集(网络、数据库、磁盘、文件)
协程+猴子补丁:处理网络io密集,将python底层的网络库改为 异步非阻塞,同步异步是执行方式,阻塞非阻塞是执行状态
互斥锁:一种让多个线程安全、有序的访问内存空间的机制。
GIL:从根本上杜绝 多个线程访问内存空间的安全隐患。

8. 采集多页/多级数据

多页采集数据:
1. 通过自增量控制页码值: 适合处理json文件响应的提取,没有下一页也不确定总页码值,但是可以一直自增偏移量控制页码的翻页,并判断响应是否有数据,来决定是否继续采集。

2. 通过提取 “下一页”连接方式处理多页采集:适合html文件的采集,依赖于网页的 a 标签提取,可以动态的获取所有页面数据,并再最后一页结束提取。

3. 将所有url地址全部保存到start_urls中(可以通过列表推导式、读取磁盘文件、数据库等),前置条件必须提供所有待发的url地址。

多级页面数据采集:
1. 不同页面的数据,保存在不同的item对象中

2. 不同页面的数据,保存在同一个item对象

Spider-five的更多相关文章

  1. spider RPC入门指南

    本部分将介绍使用spider RPC开发分布式应用的客户端和服务端. spider RPC中间件基于J2SE 8开发,因此需要确保服务器上安装了JDK 8及以上版本,不依赖于任何额外需要独立安装和配置 ...

  2. Scrapy:为spider指定pipeline

    当一个Scrapy项目中有多个spider去爬取多个网站时,往往需要多个pipeline,这时就需要为每个spider指定其对应的pipeline. [通过程序来运行spider],可以通过修改配置s ...

  3. spider RPC过滤器

    spider支持在请求执行前或完成后进行特殊处理,比如安全性检查.敏感字段混淆等等.为此,spider提供了BeforeFilter和AfterFilter.其执行位置如下图所示: 流水线插件配置在s ...

  4. spider RPC插件化体系

    为了满足灵活扩展的需要,spider支持灵活的自定义插件扩展,从功能上来说,插件和过滤器的差别在于过滤器不会阻止请求的执行同时对于主程序不会有API上的影响(比如servlet 过滤器和监听器)(最多 ...

  5. spider RPC管理接口

    为了在独立管理模式下尽可能的容易运行时排查问题,spider中间件提供了一系列restful api用于动态管理当前节点的路由,下游节点等.目前支持的RESTFUL API如下所示: 功能 服务号 R ...

  6. spider RPC高级特性

    多租户 spider原生支持多租户部署,spider报文头对外开放了机构号.系统号两个属性用于支持多租户场景下的路由. 多租户场景下的路由可以支持下述几种模式: n  系统号: n  系统号+服务号( ...

  7. spider RPC安全性

    spider提供了多重安全保障机制,目前主要支持接入握手校验,报文完整性校验,报文加密,报文长度检查四种机制. 接入认证 spider使用两次握手校验,其握手流程如下: 签名AES加密的方式实现. l ...

  8. spider RPC开发指南

    协议与兼容性 spider使用java语言开发,使用Spring作为IoC容器,采用TCP/IP协议,在此基础上,结合SaaS系统模式的特性进行针对性和重点设计,以更加灵活和高效的满足多租户系统.高可 ...

  9. spider 配置文件参考

    spider有一个配置文件spider.xml,为xml格式,spider.xml采用DTD进行管理,用于管理spider的所有特性.路由.高可用等. 配置文件支持三种不同的方式进行指定: 1. 通过 ...

  10. spider RPC性能测试报告

    测试环境部署结构 测试用例 类 别 说明 请求报文 194字节({"systemId":"PL","appVersion":"qq ...

随机推荐

  1. 吴恩达机器学习笔记29-神经网络的代价函数(Cost Function of Neural Networks)

    假设神经网络的训练样本有

  2. python_正则表达式概述

    正则表达式(RegularExpression, re) - 是一个计算机科学的概念- 用于使用单个字符串来描述,匹配符合某个规则的字符串- 常常用来检索,替换某些模式的文本 # 正则的写法- .(点 ...

  3. Oracle创建表空间创建用户和用户授权

    今天要创建一个Oracle用户,然后发现sql不太记得了,然后只能再去找找资料,发现这样效率并不是很高,所以记录成博客,有需要就直接从博客复制. 下面是我简单整理的,有需要可以参考. --创建表空间 ...

  4. 分布式作业 Elastic Job 如何动态调整?

    前面分享了两篇分布式作业调度框架 Elastic Job 的介绍及应用实战. ElasticJob-分布式作业调度神器 分布式作业 Elastic Job 快速上手指南! Elastic Job 提供 ...

  5. 一道题引出对LinkedList源码的研究

    题目:打开一个文本文件,每次读取一行内容,将每行作为一个String读入,并将那个String对象置入一个LinkedList中,按照相反的顺序打印出LinkedList中的所有行. 解题代码: pu ...

  6. springboot Aop 统一处理Web请求日志

    1.增加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  7. linux服务器部署tomcat和Nginx

    项目需要,申请了三台测试机器,好在测试机里面光秃秃的什么都没有,我就可以好好的学习一把玩一把了!接下来以图文的形式讲一下我所碰到的坑以及小小的收获吧! 一.准备工作 首先你得有一台可以玩的linux服 ...

  8. C语言 标准输入 清空缓存

  9. MySQL中字段字符集不同导致索引不能命中

    今天写了一个sql,其中涉及的表中的数据量都差不多为50w左右,查询发现用了8s.这个只是测试服上数据,放到正式服上,肯定一运行就挂了. SELECT Orders. NO, GuidNo, Orde ...

  10. [EOJ629] 两开花

    Description 给定一棵以 \(1\) 为根 \(n\) 个节点的树. 定义 \(f(k)\) :从树上等概率随机选出 \(k\) 个节点,这 \(k\) 个点的虚树大小的期望. 一个点 \( ...