Scrapy入门-Scrapy简介
Scrapy框架介绍
Scrapy是由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。
Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持
Scrapy框架的运行原理:
Scrapy Engine:负责组件之间数据的流转,当某个动作发生时触发事件。
Scheduler:接收requests,并把他们入队,以便后续的调度。
Spiders:用户编写的可定制化的部分,负责解析response,产生items和URL。
Item Pipeline:负责处理item,典型的用途:清洗、验证、持久化。
Downloadermiddlewares:位于引擎和下载器之间的一个钩子,处理传送到下载器的requests和传送到引擎的response(若需要在Requests到达Downloader之前或者是responses到达spiders之前做一些预处理,可以使用该中间件来完成)。
Spidermiddlewares:位于引擎和抓取器之间的一个钩子,处理抓取器的输入和输出 (在spiders产生的Items到达Item,Pipeline之前做一些预处理或response到达spider之前做一些处理)。
Scrapy爬虫框架的具体使用步骤如下:
Scrapy进阶-女神图片抓取并储存
1.新建项目
1scrapy startproject scrapy1
2#进入spiders目录
3scrapy genspider yaya win4000.com
创建一个scrapy项目,进入spiders目录后,会生成一个spiders的py文件,命名为yaya,win4000.com是我们要抓取网站的域名。
2.编写items
打开items文件
1import scrapy
2class ImageItem(scrapy.Item):
3 url = scrapy.Field()
items是相当于一个容器,把抓取到的各种信息可以先在这里走个过场,然后方便传到pipelines里,这里只需要导入scrapy,定义一个url就行,这个url就是之后我们抓取到的图片的链接。
3.编写spider
打开yaya,这是爬虫的核心所在:
1import scrapy
2from scrapy1.items import ImageItem
3class ImageDlnSpider(scrapy.Spider):
4 name = 'yaya'
5 allowed_domains = ['win4000.com']
6 start_urls = ['http://www.win4000.com/mt/tongliya.html']
7 def parse(self, response):
8 img_list = response.xpath("//div[@class='Left_bar']//img/@src").extract()
9 for url_list in img_list:
10 item = ImageItem()
11 item['url'] = [url_list]
12 yield item
这里先把items里的ImageItem类导入,因为我们需要对url字段进行操作,ImageDlnSpider类中,name是爬虫的名字,要保证这是唯一的,allowed_domains允许的域名,start_urls起始的抓取链接,它会调用parse函数,parse函数中便是抓取的过程了,非常简单,使用scrapy已经封装好的xpath,在for循环中实例ImageItem类,把链接赋值于item['url'],再yield出去,yield也是scrapy中非常重要的用法,后面的文章会有介绍。
4.编写settings
打开settings文件:
1ROBOTSTXT_OBEY = False
2#不遵守爬虫守约
3
4ITEM_PIPELINES = {
5 # 'image.pipelines.ImagePipeline': 300,
6'scrapy.pipelines.images.ImagesPipeline':100,
7#激活这个管道
8}
9
10IMAGES_URLS_FIELD = "url"
11#需要下载的图片链接是items里定义的url
12IMAGES_STORE = ".\\"
13#图片存储地址
5.运行爬虫
在yaya.py所在的文件夹下打开命令行:
1scrapy crawl yaya
便会运行爬虫
在spiders同目录下有个full文件夹,里边有女神照片哦。
scrapy实例-ItemLoader详解
好用的ItemLoader
scrapy提供了一个强大的工具类ItemLoader,本文通过一个实例介绍一些常用用法。
以链家的一个具体房源为例,我们的目标是提取出红框中的信息。
1.编写items
1import scrapyclass Scrapy1Item(scrapy.Item):
2 name = scrapy.Field()
3 type = scrapy.Field()
4 time = scrapy.Field()
5#type即是几室几厅,time是抓取的时间
2.编写spider
1import scrapy
2from scrapy.loader import ItemLoader#导入ItemLoader
3import datetime
4class YayaSpider(scrapy.Spider):
5 name = 'lianjiag'
6 allowed_domains = ['lianjia.com']
7 start_urls = ['https://sh.lianjia.com/ershoufang/107100525369.html']
8
9 def parse(self, response):
10 sel = ItemLoader(item= Scrapy1Item(),response=response)
11 #实例化ItemLoader
12
13 sel.add_xpath('name',"//div[@class='communityName']/a[1]/text()")
14 sel.add_xpath('type',"//div[@class='room']/div[1]/text()")
15 sel.add_xpath('type',"//div[@class='room']/div[2]/text()")
16 # sel.add_xpath('type',"//div[@class='room']/div[1]/text()",re='[\d+]')
17 #且后面可以加正则表达式
18 sel.add_value('time',datetime.datetime.now())
19 item_loader = sel.load_item()
20 yield item_loader
21 #记的yield出去
ItemLoader有三个常用的函数,add_xpath,add_css,add_value,前面两个功能类似,第一个参数是抓取信息的名字,第二个参数是xpath或css表达式。add_value把当前时间赋给time。第二和第三个add_xpath都是type字段,会将第二个抓取到的信息放到第一个后面。
运行结果如下:
type是一个有两个元素的列表,如何把两个元素合并起来,在很多电商网站会将商品价格拆分为多个,合并是很有必要的。只需在items文件的Scrapy1Item类中修改为下面这种形式
1from scrapy.loader.processors import Join
2type = scrapy.Field(output_processor=Join())
导入Join函数,定义output_processor即可。
运行结果:
ItemLoader抓取到的是一个列表,我们可以重定义一个Item类,取列表中的第一个元素。
在items文件中再创建一个类:
1from scrapy.loader.processors import TakeFirst
2class TeItem(ItemLoader):
3 default_output_processor = TakeFirst()
TakeFirst即是指取第一个不为空的元素。在spiders中要导入这个类,并实例化ItemLoader时用TeItem类:
1sel = ItemLoader(item= Scrapy1Item(),response=response)
大家看到这里会有一些疑问,scrapy也有简单的一些item抓取方法,只需item['name']="..."即可,通过这种方法需要在后面加上extract(),而且当项目比较庞大时会显的杂乱无章。下面介绍数据清洗,将会对output_processor一系列参数进行解释。
items进行数据清洗
processors
scrapy提供了一个processors类,里面有下列几种方法:
Join,TakeFirst,MapCompose,Compose,Identity,SelectJmes
对这几种方法的用法简单介绍一下:
1from scrapy.loader.processors import Join,TakeFirst,MapCompose,Compose,Identity,SelectJmes
2
3#以特定字符连接,示例以空连接,对字符串也能操作
4c = Join('')
5c(['a','b'])
6>>>'ab'
7#********************
8
9#传入函数的列表的每一个元素都会经过第一个函数,
10#得到值在经过第二个函数,如果有返回值为None的,则抛弃,
11#最后返回一个列表
12c=MapCompose(str.strip,str.upper)
13c([' a ','b'])
14>>>['A', 'B']
15#********************
16
17#如果传入一个列表时则会报下面这个错误
18#descriptor 'strip' requires a 'str' object but received a 'list'
19#但如果Compose的第一个函数是取列表的第一个元素,不会报错
20#即Compose是处理单一数据,MapCompose是批量处理
21c=Compose(str.strip,str.upper)
22c(' ac ')
23>>>'AC'
24#********************
25
26#拿到JSON格式数据时会有作用
27proc = SelectJmes('a')
28proc({'a':'b','c':'d'})
29>>>'b'
TakeFirst是取第一个不为空的元素,上一篇已经介绍过。
input--output
Item Loader 为每个 Item Field 单独提供了一个 Input processor 和一个 Output processor;Input processor 一旦它通过 add_xpath(),add_css(),add_value() 方法收到提取到的数据便会执行,执行以后所得到的数据将仍然保存在 ItemLoader 实例中;当数据收集完成以后,ItemLoader 通过 load_item() 方法来进行填充并返回已填充的 Item 实例。即input_processor是在收集数据的过程中所做的处理,output_processor是数据yield之后进行的处理,通过下面这个例子会更加理解:
1#type字段取出来时是'type': ['2室2厅', '中楼层/共6层']
2
3#定义一个在第一个元素后面加a的函数
4def adda(value):
5 return value[0]+'a'
6
7type = scrapy.Field(output_processor = Compose(adda))
8>>>'type': '2室2厅a'
9
10type = scrapy.Field(input_processor = Compose(adda))
11>>>'type': ['2室2厅a', '中楼层/共6层a']
12#如果使用MapCompose的话,两个结果会一样,这也是Compose和MapCompose的区别
当指定了取列表的第一个元素后,有些信息想保留整个列表便可以使用name_out,Identity()是取自身的函数。
1class TeItem(ItemLoader):
2 default_out_processor = TakeFirst()
3 name_out = Identity()
也可以在基于scrapy.Item的item中定义一些规则:
1class Scrapy1Item(scrapy.Item):
2 name = scrapy.Field(output_processor=Identity())
优先级
scrapy提供了很多种方式去自定义输入输出的内容,具有一定的优先级,优先级最高的是name_out这种,其次是在scrapy.Field()中定义的output_processor和input_processor,最后是default_out_processor = TakeFirst()这种。
总结
ItemLoader的使用可大大提高代码的可重用性,对于需要特殊函数处理的字段,也只需在items文件中定义并使用,爬虫的核心spider也会整洁,若网页发生变化,也便于修改。
关于图书
《深度学习之TensorFlow:入门、原理与进阶实战》和《Python带我起飞——入门、进阶、商业实战》两本图书是代码医生团队精心编著的 AI入门与提高的精品图书。配套资源丰富:配套视频、QQ读者群、实例源码。 深度学习之TensorFlow读者群,① 群聊号码:40016981 ② 群聊号码:786252868 让python带我起飞读者群,群聊号码:274962708
点击“阅读原文”图书配套资源
本文分享自微信公众号 - 相约机器人(xiangyuejiqiren)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/3267804/blog/4580782