《Python网络爬虫基础教程》 课件-第11章 分布式网络爬虫Scrapy-Redis_第1页
《Python网络爬虫基础教程》 课件-第11章 分布式网络爬虫Scrapy-Redis_第2页
《Python网络爬虫基础教程》 课件-第11章 分布式网络爬虫Scrapy-Redis_第3页
《Python网络爬虫基础教程》 课件-第11章 分布式网络爬虫Scrapy-Redis_第4页
《Python网络爬虫基础教程》 课件-第11章 分布式网络爬虫Scrapy-Redis_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第11章分布式网络爬虫Scrapy-Redis《Python网络爬虫基础教程》学习目标/Target了解分布式网络爬虫,能够说出采用主从模式的分布式网络爬虫的特点熟悉Scrapy-Redis的架构,能够归纳Scrapy-Redis架构的原理熟悉Scrapy-Redis的运作流程,能够归纳Scrapy-Redis的运作流程掌握开发Scrapy-Redis的准备工作,能够搭建Scrapy-Redis的开发环境掌握Scrapy-Redis的基本操作,能够灵活应用Scrapy-Redis开发分布式网络爬虫章节概述/Summary前面编写的网络爬虫都运行在单台计算机上,由于受到计算机能力和网络带宽的限制,单台计算机上运行的网络爬虫在采集大量数据时需要花费很长的时间。分布式网络爬虫正好解决了这个问题,它可以在多台计算机上同时运行同一个网络爬虫程序,共同完成一个采集任务。在Python中,Scrapy框架本身并不支持分布式,为弥补该框架的不足,Scrapy-Redis为其拓展了分布式功能,两者结合便可以实现分布式网络爬虫。本章将围绕着分布式网络爬虫Scrapy-Redis的相关知识进行详细的讲解。目录/Contents11.111.211.3分布式网络爬虫简介Scrapy-Redis架构Scrapy-Redis运作流程目录/Contents11.411.511.6Scrapy-Redis开发准备Scrapy-Redis的基本操作实践项目:使用RedisCrawlSpider采集畅购商城的华为手表信息分布式爬虫简介11.1了解分布式网络爬虫,能够说出采用主从模式的分布式网络爬虫的特点学习目标11.1分布式网络爬虫简介Scrapy框架是一个通用的网络爬虫框架,应用极其广泛,但Scrapy框架本身并不支持分布式部署,也就是说无法在多台计算机中同时执行网络爬虫程序,导致采集数据的效率受到限制。为了提升网络爬虫的采集效率,Scrapy-Redis在Scrapy的基础上增加了一些以Redis数据库为基础的组件,通过这些组件可以让Scrapy框架实现分布式网络爬虫的功能。11.1分布式网络爬虫简介分布式网络爬虫可以理解为集群爬虫,每个网络爬虫会从互联网上抓取网页数据,并将解析后提取的目标数据保存到文件或数据库中。分布式网络爬虫的设计重点在于多台计算机中的网络爬虫如何进行通信,按不同的通信方式可以分为3种模式,分别是主从模式、自治模式与混合模式。11.1分布式网络爬虫简介11.1分布式网络爬虫简介

主从模式主从模式指由一台主机作为控制节点,负责管理所有运行网络爬虫的主机,即爬虫节点,爬虫节点只需要从控制节点处接收任务,并把新生成的任务提交给控制节点即可,在整个运行过程中不必与其他爬虫节点进行通信。Scrapy-Redis实现的分布式网络爬虫默认采用了主从模式。11.1分布式网络爬虫简介

主从模式主从模式易于实现且利于管理,在这种模式下,控制节点会与所有爬虫节点进行通信。它通过一个地址列表保存系统中所有爬虫节点的信息,一旦遇到系统中的网络爬虫数量发生变化,就会更新这个地址列表。这一过程对于系统中的爬虫是透明的。不过,随着网络爬虫采集的网页数量逐渐增加,控制节点会成为整个系统的瓶颈,导致整个分布式网络爬虫的系统性能下降。11.1分布式网络爬虫简介

自治模式自治模式是指没有协调者,所有的爬虫节点相互通信的模式,它的通信方式主要有两种:全连接通信和环形通信,其中全连接通信是指所有的爬虫节点间相互发送信息;环形通信是指爬虫节点在逻辑上构成一个环形,数据沿着环形按顺时针或逆时针单向传输。11.1分布式网络爬虫简介

自治模式左图是采用全连接通信方式的自治模式,右图是采用环形通信方式的自治模式。采用全连接通信方式的每个爬虫节点会维护一个地址列表,列表中存储了系统所有爬虫节点的位置。每次通信时可以直接将数据发送给需要此数据的爬虫节点。采用环形通信方式的每个爬虫节点只会保存前驱和后继的信息,爬虫节点在接收到数据之后会判断数据是否是发送给自己的。如果数据不是发送给自己的,则爬虫节点会把数据转发给后继爬虫节点,否则不再转发数据。11.1分布式网络爬虫简介

混合模式混合模式是指结合上面两种模式的特点生成的一种折中模式,该模式下的所有爬虫节点都可以相互通信

,同时都具有任务分配的功能,只不过所有爬虫节点中有一个特殊的爬虫节点,该爬虫节点会对无法分配的任务进行集中分配。11.1分布式网络爬虫简介

混合模式混合模式下的每个爬虫节点只需要维护自己采集范围的地址列表,而特殊爬虫节点除了保存自己采集范围的地址列表外,还需要保存需要进行集中分配的地址列表。值得一提的是,Scrapy-Redis实现的分布式网络爬虫默认采用了主从模式,即一台作为控制节点的主机和若干台作为爬虫节点的主机。每个网络爬虫的功能相同,都是负责将服务器返回的Item数据和URL提交给控制节点的主机。控制节点会统一分配爬虫节点提交的任务,它在分配时并非是将某台主机提交的任务分配给该主机,而是发现哪台主机处于空闲状态,便为该主机分配任务。Scrapy-Redis架构11.2熟悉Scrapy-Redis的架构,能够归纳Scrapy-Redis架构的原理学习目标11.2Scrapy-Redis架构11.2Scrapy-Redis架构Scrapy-Redis不是一个框架,而是一些组件。借用下面的一个例子区分Scrapy和Scrapy-Redis的关系:假如把Scrapy看作一个工厂,这个工厂主要负责根据用户的需求生产网络爬虫,那么Scrapy-Redis便是其他厂商,它为了帮助工厂更好地完成生产任务制造了一些新设备,以替换Scrapy工厂的原有设备。11.2Scrapy-Redis架构对比Scrapy的架构可知,Scrapy-Redis在Scrapy架构的基础上增加了两个组件,分别是Redis和ItemProcesses,其中Redis是一个Key-Value数据库,它负责存放由Scheduler传递的待抓取请求,如此每台计算机上的爬虫都会访问同一个Redis数据库,通过这个数据库实现对请求的调度和判重进行统一管理;ItemProcesses组件表示Item集群。11.2Scrapy-Redis架构根据Redis的特性,Scrapy-Redis在Scrapy原生组件的基础上拓展了4个组件:Scheduler、ItemPipeline、Spiders和DuplicationFilter。

SchedulerScrapy框架对Python原有的双向队列进行了改造,形成了自己的ScrapyQueue,但ScrapyQueue不能被多个Spiders共用,使得Scrapy框架不支持分布式采集。为此Scrapy-Redis将ScrapyQueue替换成了Redis数据库,由一个Redis数据库统一存放待发送的请求,这样可以让多个Spiders从同一数据库中读取请求。在Scrapy框架中,与待发送请求直接相关的组件是调度器Scheduler,该组件负责将新的请求添加到队列中,并从该队列中取出下一个要发送的请求。Scrapy原有的Scheduler已经无法使用,换成了Scrapy-Redis的Scheduler组件。11.2Scrapy-Redis架构

ItemPipeline在Scrapy框架中,当Spiders采集到Item数据时,ScrapyEngine会把Item数据交给ItemPipeline,再由ItemPipeline把Item数据保存到Redis数据库中。Scrapy-Redis对Scrapy框架的ItemPipeline组件进行了修改,它可以很方便地根据键访问Redis数据库中的Item数据,从而实现Item集群。11.2Scrapy-Redis架构

SpidersScrapy-Redis中Spiders组件不再使用Scrapy原有的Spider类表示爬虫,而使用重写的RedisSpider类。RedisSpider类继承了Spider类和RedisMixin这两个类。当创建了一个继承自RedisSpider的子类对象时,该对象调用setup_redis()方法后会连接Redis数据库,满足一定条件后会设置如下两个信号。爬虫节点的主机处于空闲状态的信号,这个信号会被ScrapyEngine识别,判断网络爬虫当下是否处于空闲状态。采集到一个Item数据的信号,这个信号仍然会被ScrapyEngine识别,判断网络爬虫是否采集到Item数据。11.2Scrapy-Redis架构

DuplicationFilter11.2Scrapy-Redis架构Scrapy使用集合实现请求的去重功能。它会把已经发送的请求指纹(请求的特征值)放到一个集合中,然后在该集合中比对下一个请求指纹。如果该请求指纹存在于该集合中,则说明这个请求已经被发送,否则继续操作。Scrapy-Redis中使用DuplicationFilter组件实现的请求的去重功能,该组件利用Redis中set集合元素不重复的特点,巧妙地实现了这个功能。首先Scheduler接收ScrapyEngine传递的请求指纹,然后将这个请求指纹存入set集合中检查是否重复,并把不重复的请求指纹加入到Redis的请求队列中。Scrapy-Redis运作流程11.3熟悉Scrapy-Redis的运作流程,能够归纳Scrapy-Redis的运作流程学习目标11.3Scrapy-Redis运作流程(1)ScrapyEngine从Spiders中获取初始URL。(2)ScrapyEngine将初始URL封装成请求,并将该请求交给Scheduler。(3)Scheduler访问Redis数据库对请求进行判重,如果该请求不是重复的,就将该请求添加到Redis数据库中。(4)当调度条件满足时,Scheduler会从Redis数据库中取出Request交给ScrapyEngine,ScrapyEngine将这个Request通过DownloaderMiddlewares转交给Downloader。11.3Scrapy-Redis运作流程Scrapy-Redis的运作流程如下。11.3Scrapy-Redis运作流程Scrapy-Redis的运作流程如下。(5)一旦页面下载完毕,Downloader会将服务器返回的响应通过DownloaderMiddlewares交给ScrapyEngine。(6)ScrapyEngine通过SpiderMiddlewares发送给Spiders进行处理。(7)Spiders处理响应,并返回采集到的Item数据以及新Request交给ScrapyEngine。(8)ScrapyEngine将爬取到的Item数据通过ItemPipeline交给Redis数据库,将Request给Scheduler。(9)从第2步开始重复,直到Scheduler中没有更多的Request为止。Scrapy-Redis开发准备11.4掌握Scrapy-Redis安装方式,能够在Windows7操作系统中通过pip进行安装学习目标11.4.1安装Scrapy-Redis安装Scrapy-Redis的方式非常简单,可以直接通过pip工具安装Scrapy-Redis库。pipinstallscrapy-redis==0.7.111.4.1安装Scrapy-Redis运行上述命令,在命令行窗口中可以看到不断输出的安装信息。Scrapy-Redis库安装完成的窗口。安装成功掌握修改Redis配置文件的方式,能够通过修改配置文件允许其他客户端远程连接到Redis服务学习目标11.4.2修改配置文件11.4.2修改配置文件在Windows系统下,Redis数据库的配置文件是redis.windows.conf,该文件默认位于数据库的安装目录下。在配置文件中,bind配置项用于指定绑定的主机地址,默认值为bind,即本机地址,说明只允许本机的客户端访问Redis服务,而不允许其他客户端远程连接Redis服务,防止Redis服务暴露于危险的网络环境中,被其他客户端随意连接。11.4.2修改配置文件以Windows7系统为例,使用文本编辑工具打开redis.windows.conf文件,将该文件中的配置项bind改为bind。redis.windows.conf文件中默认开启了保护模式,此时需要将配置项protected-modeyes改为protected-modeno,以关闭保护模式。熟悉测试远程连接的步骤,能够测试爬虫节点的设备是否能读取Redis数据库中数据学习目标11.4.3测试远程连接11.4.3测试远程连接为保证爬虫节点的设备能够读取Redis数据库中的数据,我们在在执行分布式网络爬虫程序之前需要进行远程连接测试,保证爬虫节点(Slave端)的所有设备可以正常远程连接控制节点(Master端)的Redis数据库。假设现有3台分别装有Windows7、macOS和Ubuntu系统的计算机,其中装有Windows7系统的计算机为Master端,其他两台计算机为Slave端,需要测试Slave端能否可以正常连接到Master端并访问Redis数据库。11.4.3测试远程连接测试远程连接具体步骤如下。(1)在Master端的计算机上以管理员身份打开命令行窗口,然后根据指定的配置文件启动redis-server。redis-serverredis.windows.conf(2)在Master端的计算机上再次打开新命令行窗口,使用如下命令启动本地客户端redis-cli。redis-cli11.4.3测试远程连接测试远程连接具体步骤如下。(3)在本地客户端中输入ping命令检测本地客户端是否可以连接Redis服务,若连接正常再使用set命令向Redis数据库添加两个键值对。ping命令结果为PONG,说明客户端可以正常连接Redis服务11.4.3测试远程连接测试远程连接具体步骤如下。(4)Slave端的计算机要想连接Master端的Redis数据库,需要在启动客户端时指定Master端的IP地址,若本例中Master端的IP地址为08。在Slave端的终端中输入如下命令启动redis-cli。redis-cli-h08-h参数表示连接到指定主机的Redis数据库。值得一提的是,Slave端的计算机无需无须启动redis-server。11.4.3测试远程连接测试远程连接具体步骤如下。(5)因为在前面已经向Redis数据库中存入了两个键值对,所以可以在Slave端中直接使用get命令获取Redis数据库中的键值对进行测试,一旦准确获取到该键对应的值,说明Slave端的网络爬虫可以正常访问Redis数据库。装有macOS系统的计算机执行命令后的结果装有Ubuntu系统的计算机执行命令后的结果多学一招查看计算机的IP地址在Windows系统的命令提示符窗口中,可使用如下命令查看IP地址。ipconfig以上命令执行后,可以看到WindowsIP配置的具体信息,其中IPv4地址选项对应的值便是当前计算机的IP地址,具体如下所示。WindowsIP配置以太网适配器本地连接:

连接特定的DNS后缀.......:

本地链接IPv6地址........:fe80::8d8d:90f0:3afd:f945%11IPv4地址............:08...省略N行...Scrapy-Redis的基本操作11.5Scrapy-Redis可以看作Scrapy框架的插件,它里面重新实现了Scrapy框架中部分组件的功能,使Scrapy框架支持开发分布式网络爬虫。因此,可以先创建一个Scrapy项目,然后在Scrapy项目中增加Scrapy-Redis的相关配置,并使用替换的组件进行开发。11.5Scrapy-Redis的基本操作掌握内置下载中间件的使用,能够在爬虫项目启用下载中间件学习目标11.5.1新建Scrapy-Redis项目打开命令提示符窗口,先切换当前工作路径为项目要存放的目录,再输入创建Scrapy项目的命令,具体命令如下。11.5.1新建Scrapy-Redis项目scrapystartprojectmyDistributedSpider运行上述命令,可以在爬虫目录下看到刚刚创建的myDistributedSpider项目。11.5.1新建Scrapy-Redis项目DUPEFILTER_CLASS用于设置检测与过滤重复请求的类。需要使用Scrapy-Redis的去重组件,交由Redis数据库执行去重操作。DUPEFILTER_CLASSDUPEFILTER_CLASS="scrapy_redis.dupefilter.RFPDupeFilter"SCHEDULER用于设置调度器。这里,我们需要使用Scrapy-Redis的调度器,交由Redis分配请求。SCHEDULERSCHEDULER="scrapy_redis.scheduler.Scheduler"在创建的Scrapy-Redis项目的settings.py文件可增加或修改与Scrapy-Redis相关的配置项。11.5.1新建Scrapy-Redis项目在创建的Scrapy-Redis项目的settings.py文件可增加或修改与Scrapy-Redis相关的配置项。SCHEDULER_PERSIST用于设置是否在Redis数据库中保持用到的队列。这里,我们无须清理Redis中使用的队列,允许项目在执行中暂停和暂停后恢复。SCHEDULER_PERSISTSCHEDULER_PERSIST=TrueITEM_PIPELINES用于设置启用管道,它的值是一个包含所有项目管道的字典,默认是不启用的。启用该配置项后,Scrapy-Redis会将爬虫抓取的Item数据存储到Redis数据库中。ITEM_PIPELINESITEM_PIPELINES={'myDistributedSpider.pipelines.MydistributedspiderPipeline':100,}11.5.1新建Scrapy-Redis项目REDIS_HOST用于设置Redis数据库的连接信息,分别表示Redis所在主机的IP地址。REDIS_HOSTREDIS_HOST='08'REDIS_HOST用于设置Redis数据库的连接信息,分别表示Redis所在主机的端口。REDIS_PORTREDIS_PORT=6379在创建的Scrapy-Redis项目的settings.py文件可增加或修改与Scrapy-Redis相关的配置项。明确爬虫项目中明确采集目标,能够在Scrapy-Redis中添加爬取字段学习目标11.5.2明确采集目标11.5.2明确采集目标myDistributedSpider项目要采集的目标数据仍然是某培训公司的讲师详情页中的讲师信息,包括讲师的姓名、级别和履历,由于采集目标与第9章案例的采集目标一致,所以仍然添加3个表示讲师姓名、讲师级别和讲师履历的属性。importscrapyclassMydistributedspiderItem(scrapy.Item):name=scrapy.Field()#表示讲师姓名

level=scrapy.Field()#表示讲师级别

resume=scrapy.Field()#表示讲师履历将mySpider\items.py文件中添加属性的代码复制到myDistributedSpider\items.py文件中掌握制作Scrapy爬虫,能够使用Scrapy-Redis提取指定数据学习目标11.5.3制作爬虫Scrapy-Redis的scrapy_redis.spiders模块中定义了两个代表爬虫的类:RedisSpider和RedisCrawlSpider,其中RedisSpider是Spider的派生类,RedisCrawlSpider是CrawlSpider类的派生类,这两个类默认已经拥有了父类中的成员,此外也定义了自己的属性,如redis_key和allowed_domains属性。11.5.3制作爬虫

redis_key属性redis_key属性用于设置Redis数据库从哪里获取初始URL,作用类似于start_urls属性。redis_key属性的值是一个字符串,字符串中的内容一般是爬虫名称和start_urls,且两者之间以冒号进行分隔。redis_key=‘itcast:start_urls‘#itcast为爬虫名称

运行Scrapy-Redis项目后,所有的爬虫不会立即执行抓取操作,而是在原地等待Master端发布指令,这是因为所有的爬虫已经没有初始URL了,而是由Redis数据库统一分配与调度采集任务,从Redis数据库中获取请求。11.5.3制作爬虫

allowed_domains属性11.5.3制作爬虫allowed_domains属性的作用与之前allowed_domains属性相同,用于设置爬虫搜索的域名范围。allowed_domains属性的值有两种设置方式,一种是按照Spider的原有写法,直接赋值为爬虫搜索的域名范围,另一种方式是动态地获取域名。def__init__(self,*args,**kwargs):domain=kwargs.pop('domain','')self.allowed_domains=filter(None,domain.split(','))super(当前类名,self).__init__(*args,**kwargs)11.5.3制作爬虫我们在myDistributedSpider项目下创建一个爬虫:爬虫的名称为itcast,爬虫搜索的域名范围为,具体命令如下。scrapygenspideritcast""运行上述命令,可以看到myDistributedSpider/spiders目录下增加了itcast.py文件。在itcast.py文件需要将ItcastSpider的父类修改为RedisSpider类,删除start_urls属性的代码,增加设置redis_key属性的代码,并在parse()方法中实现解析目标网页数据的功能。[单击查看源码]掌握如何运行Scrapy-Redis爬虫,能够启动分布式爬虫学习目标11.5.4运行爬虫11.5.4运行爬虫制作爬虫完成之后,我们就可以采用分布式方式运行网络爬虫程序了。在执行爬虫之前,需要先确定计算机的分配情况,选择哪台计算机为控制节点的主机,负责给其他计算机提供URL分发服务,哪台计算机为爬虫节点的主机,负责执行网页的采集任务,并保证爬虫节点可以成功读取控制节点上Redis数据库中存放的数据。运行分布式爬虫的步骤如下。(1)在Master端的计算机中,打开命令行窗口,切换当前路径为Redis数据库的安装目录,之后输入如下命令启动redis-server。redis-serverredis.windows.conf11.5.4运行爬虫(2)将myDistributedSpider项目复制到Slave端。在Slave端的计算机中打开命令行窗口,将当前工作路径切换至myDistributedSpider/spiders目录下。scrapyrunspideritcast.py运行以上命令,此时Slave端的计算机会暂停执行,等待Master端发布指令。值得一提的是,多个Slave端在运行爬虫时无需区分先后顺序。(3)在Master端的计算机中,再次打开一个命令行窗口,输入如下命令启动redis-cli。redis-cli(4)使用lpush命令发布指令到Slave端。lpush命令有着固定的格式,具体如下。11.5.4运行爬虫lpushredis_key初始URL例如,使用lpush命令发布指令采集讲师的信息,具体命令如下lpushitcast:start_urls/channel/teacher.shtml运行上述命令,Slave端的命令行窗口中不断地输出提示信息,开始爬取数据。掌握如何在Scrapy-Redis中使用管道,能够使用管道存储数据学习目标11.5.5使用管道存储数据在Scrapy-Redis项目中,同样也可以定义多个管道,并让这些管道按照一定的顺序依次处理Item数据。11.5.5使用管道存储数据每个管道都是一个独立的Python类,并在该类中必须实现process_item()方法。例如,定义3个管道类:ItacstCsvPipeline类、ItacstRedisPipeline类和ItacstMongoPipeline类。11.5.5使用管道存储数据

定义管道11.5.5使用管道存储数据

定义管道ItacstCsvPipeline类ItacstCsvPipeline类负责将数据保存到CSV文件。为方便开发人员读写CSV格式的文件,这里需要结合scrapy.exporters模块中CsvItemExporter类的功能,对Item数据进行相应的处理。open_spider()方法指定了爬虫运行前执行的操作,process_item()方法指定了爬虫对Item数据的处理操作,close_spider()方法指定了爬虫运行后执行的操作,fromscrapy.exportersimportCsvItemExporterclassItcastCsvPipeline(object):defopen_spider(self,spider):self.file=open("itcast.csv","w")#根据CSV文件创建文件对象self.csv_exporter=CsvItemExporter(self.file)#创建CsvItemExporter类的对象self.csv_exporter.start_exporting()#标识开始导出文件defprocess_item(self,item,spider):self.csv_exporter.export_item(item)#将Item数据写入文件中returnitemdefclose_spider(self,spider):self.csv_exporter.finish_exporting()#标识结束导出文件

self.file.close()#关闭文件11.5.5使用管道存储数据

定义管道ItacstCsvPipeline类ItcastCsvPipeline类的定义如右。importredis,jsonclassItcastRedisPipeline(object):defopen_spider(self,spider):#建立与Redis数据库的连接

self.redis_cli=redis.Redis(host="9",port=6379)#建立与Redis数据库的连接defprocess_item(self,item,spider):#指定了爬虫对Item数据的处理操作。

content=json.dumps(dict(item),ensure_ascii=False)#将Item数据转换成JSON对象self.redis_cli.lpush("ITCAST_List",content)#将content插入Redis数据库returnitem11.5.5使用管道存储数据

定义管道ItacstRedisPipeline类ItacstRedisPipeline类负责将数据保存到Redis数据库。importpymongoclassLtcastMongoPipeline(object):#指定了爬虫运行前执行的操作defopen_spider(self,spider):

self.mongo_cli=pymongo.MongoClient(host="",port=27017)#建立与MongoDB数据库的连接

self.db=self.mongo_cli["itcast"]#创建数据库

self.sheet=self.db['itcast_item']#创建集合defprocess_item(self,item,spider):#指定了爬虫对Item数据的处理操作self.sheet.insert(dict(item))returnitem11.5.5使用管道存储数据

定义管道ItacstMongoPipeline类ItacstMongoPip

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论