# srapy框架 # 什么是框架——就是一个集成了很多功能并且具有很强通用性的项目模板 # 如何学习框架——专门学习框架封装的各种功能的详细用法 # 什么是scrapy——爬虫中封装好的一个明星框架 # 功能:高性能的持久化存储操作、异步的数据下载,高性能的数据分析 、分布式爬虫 # ssrapy的基本使用 ——环境的安装 pip install wheel 下载twisted,下载地址为http://www.lfd.uci.edu/~gohlke/pythonlib/#twist # 安装twisted:pip install Twisted-17.1.0-cp35-cp35m-win_amd64.whl # pip install pywin32 # pip install scrapy # 测试:再终端中录入scrapy指令,没有报错即表示安装成功 # 创建一个工程:scrapy startproject xxproject(spiders爬虫文件、setting》py) # cd XXXpro 再spiders子目录中创建一个爬虫文件 ——scrapy genspider spiderName www.xxx.com # 执行 -scrapy crawl spiderName # scrapy数据解析 # scrapy持久化存储 :-基于终端指令 (要求:只可以将parse方法的返回值存储到本地的文本文件中,持久化存储对应的文本,持久化存储对应的文本文件的类型只可以为json、jsonlines、jl、csv、xml等) # 指令:scrapy crawl XXX -o filePath # 好处:简洁高效便捷 缺点:局限性强 # -基于管道:(重要) 通用性强 # 编码流程: # 数据解析 # 在item类中定义相关的属性 name=scrapy.Field() # 将解析的数据封装存储到item类型的对象 导入新类 from qiubaiPro import item item['author']=author # 将item类型的对象提交给管道进行持久化存储操作 yield item # 在管道类的process——item中要将其接收到的item对象中存储的数据进行持久化存储 # 在配置文件中开启管道 # ITEM_PIPELINES={'qiubaiPro.pipelines.QiubaiproPipeline':300} # import scrapy class qiubaiSpider(scrapy.Spider): name='qiubai' allowed_domains=['www.xxx.com'] start_url=['http://www.xxx.com'] def parse(self,response): pass # 解析:作者的名称+段子内容 div_list=response.xpath('//div[@id="content-left"]/div') all_data=[] for div in div_list: # xpath返回的是列表,但是列表元素一定是selector类型的对象 # extract可以将selector对象中data参数存储的字符串提取出来 author=div.xpath('./div[1]/a[2]/h2/text()') .extract() content=div.xpath('./a[1]/div/span//text()') .extract() # 列表调用了extract之后,则表示将列表中每一个selector对象中data对应的字符串返回 dic={'author':author, 'content':content} all_data.append(dic) return all_data # crawlspider 是spider的一个子类,之前创建的爬虫文件的爬虫类的父类就是spider # 作用:用于实现全站数据爬取 # 基本使用 def parse(self,response): pass # 解析:作者的名称+段子内容 div_list=response.xpath('//div[@id="content-left"]/div') all_data=[] for div in div_list: # xpath返回的是列表,但是列表元素一定是selector类型的对象 # extract可以将selector对象中data参数存储的字符串提取出来 author=div.xpath('./div[1]/a[2]/h2/text()') .extract() content=div.xpath('./a[1]/div/span//text()') .extract() # 列表调用了extract之后,则表示将列表中每一个selector对象中data对应的字符串返回 dic={'author':author, 'content':content} all_data.append(dic) return all_data class QiubaiproPipeline(object): fp=None def open_spider(self,spider): print('开始爬虫。。。') self.fp=open('./qiubai.txt','w',encoding='utf-8') def process_item(self,item,spider): author=item['author'] content=item['content'] self.fp.write(author+":"+content+'\n') return item def close_spider(self,spider): print('结束爬虫') fp.close() # 基于spider的全站数据爬取 # -就是将网站中某板块下的全部页码对应的页面数据进行爬取 # -需求:爬取校花网中的照片名称 # 实现方式:将所有页面的url添加到start_urls列表(不推荐) # 自行手动进行请求发送(推荐) # 手动请求发送:yield.Request(url,callback) callback专门用作数据解析 # scrapy的五大核心组件:管道、调度器、引擎(数据流处理 可以触发事件)、下载器、spider # import scrapy class xiaohuaSpider(scrapy.Spider): name='xiaohua' start_url=['http://www.521609.com/meinvxiaohua/'] url='http://www.521609.com/meinvxiaohua/list12%d.html' page_num=2 def parse(self,response): li_list=response.xpath('//*[@id="content"]/div[2]/div[2]/ul/li') for li in li_list: image_name=li.xpath('./a[2]/b/text()|./a[2]/text()').extract() print(image_name) if self.page_num<=11: new_url=format(self.url%self.page_num) self.page_num+=1 yield scrapy.Request(url=new_url,callback=self.parse) # 五大核心组件: # 引擎(scrapy):用来处理整个系统的数据流,触发事务(框架核心) # 调度器:用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回,可以想象成一个url # 下载器:用于下载网页内容,并将网页内容返回给蜘蛛 # 爬虫:爬虫主要是干活的,用于从特定的网页中提取自己需要的信息,即所谓的实体, # 项目管道:负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性 # 请求传参 # 使用场景:如果爬取解析的数据不在同一个页面中。(深度爬取) # -需求:爬取boss的岗位名称 岗位描述 # yield.scrapy.Request(url,callback,meta) meta={},可以将meta字典传递给请求对应的回调函数 # import scrapy class BossSpider(scrapy.Spider): name='boss' start_urls=['https://www.zhipin.com'] url='https://www.zhipin.com' page_num=2 def parse(self,response): # 接受参数item item=response.meta['item'] job_desc=response.xpath('//*[id="main"]/div[3]/div/div[2]/div[2]/div[1]/div[2]/div//text()').extract() job_desc=''.join(job_desc) item['job_desc']=job_desc def parse(self,response): item=BossproItem() li_list=response.xpath('//*[id="main"]/div/div[3]/ul/li') for li in li_list: job_name=li.xpath('.//div[@class="info-primary"]/h3/a/div[1]/text()').extract() detail_url=li.xpath('.//div[@class="info-primary"]/h3/a/@href').extract() # 对详情页发送请求 获取详情页的页面原码数据 item['job_name']=job_name yield scrapy.Request(detail_url,callback=self.parse_detail,meta={'item':item}) # 进行分页操作 if self.page_num<=11: new_url=format(self.url%self.page_num) self.page_num+=1 yield.scrapy.Request(url=new_url,callback=self.parse)
imagepipeline
# 图片数据爬取之ImagePipeline # -基于scrapy爬取字符串类型的数据和爬取图片类型的数据有什么区别? # -字符串:只需要基于xpath进行解析且提交管道进行持久化存储 # -图片:xpath解析出图片src的属性值。单独对图片地址发起请求获取图片二进制类型的数据 # ImagePipeline:只需要将img的src属性值进行解析,提交到ImagePipeline后,管道会自动的对图片的src进行请求发送获取图片二进制累心的数据 并进行持久化存储 # -需求:爬取站长素材中的高清图片 # -使用流程: # import scrapy # from imagePro.item import ImageproItem class imageSpider(scrapy.Spider): name='image' start_urls=['http://sc.chinaz.com/tupian/'] def parse(self,response): div_list=response.xpath('//div[@id="container"]/div') for div in div_list: # 注意:在进行解析的时候 要注意使用伪属性 伪属性:在本案例中,图片只有进入可视化页面的时候 原码才会露出真实属性 src=div.xpath('./div/a/img/@src2').extract_first() item=ImageproItem() item['src']=src yield item