zoukankan      html  css  js  c++  java
  • Spider-five

    一、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对象

     

  • 相关阅读:
    团队二阶段冲刺个人工作总结9
    团队二阶段冲刺个人工作总结8
    团队二阶段冲刺个人工作总结7
    团队二阶段冲刺个人工作总结6
    PSP总结报告
    第十三周例行报告
    对团队成员公开感谢博客
    附加作业 软件工程原则的应用实例分析
    第十二周例行报告
    第十一周例行报告
  • 原文地址:https://www.cnblogs.com/hsmwlyl/p/10636571.html
Copyright © 2011-2022 走看看