Scrapy入门实例教程

浪尽此生 提交于 2020-11-13 05:53:46

Scrapy入门-Scrapy简介


Scrapy框架介绍


  • ScrapyPython语言开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。

  • Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

  • Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpidersitemap爬虫等,最新版本又提供了web2.0爬虫的支持


Scrapy框架的运行原理:


 


Scrapy Engine负责组件之间数据的流转,当某个动作发生时触发事件。

 

Scheduler接收requests,并把他们入队,以便后续的调度。

 

Spiders用户编写的可定制化的部分,负责解析response,产生itemsURL

 

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目录后,会生成一个spiderspy文件,命名为yayawin4000.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_xpathadd_cssadd_value,前面两个功能类似,第一个参数是抓取信息的名字,第二个参数是xpathcss表达式。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 processorInput 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_outIdentity()是取自身的函数。

1class TeItem(ItemLoader):
2    default_out_processor = TakeFirst()
3    name_out = Identity()

也可以在基于scrapy.Itemitem中定义一些规则:

1class Scrapy1Item(scrapy.Item):
2    name = scrapy.Field(output_processor=Identity())


优先级

scrapy提供了很多种方式去自定义输入输出的内容,具有一定的优先级,优先级最高的是name_out这种,其次是在scrapy.Field()中定义的output_processorinput_processor,最后是default_out_processor = TakeFirst()这种。

 

总结     

ItemLoader的使用可大大提高代码的可重用性,对于需要特殊函数处理的字段,也只需在items文件中定义并使用,爬虫的核心spider也会整洁,若网页发生变化,也便于修改。

 

关于图书

《深度学习之TensorFlow:入门、原理与进阶实战》和《Python带我起飞——入门、进阶、商业实战》两本图书是代码医生团队精心编著的 AI入门与提高的精品图书。配套资源丰富:配套视频、QQ读者群、实例源码。 深度学习之TensorFlow读者群,① 群聊号码:40016981  ② 群聊号码:786252868    让python带我起飞读者群,群聊号码:274962708


点击“阅读原文”图书配套资源

本文分享自微信公众号 - 相约机器人(xiangyuejiqiren)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!