【Python3 爬虫学习笔记】Scrapy框架的使用 2

运行

进入Scrapy创建的目录,运行如下命令:

scrapy crawl quotes

首先,Scrapy输出了当前的版本号以及正在启动的项目名称。接着输出了当前settings.py中一些重写后的配置。然后输出了当前所应用的Middlewares和Pipelines。Middlewares默认是启动的,可以在settings.py中修改。Pipelines默认是空,同样页可以在settings.py中配置。
接下来就是输出各个页面的抓取结果了,可以看到爬虫一边解析,一边翻页,直至将所有内容抓取完毕,然后终止。
最后,Scrapy输出了整个抓取过程的统计信息,如请求的字节数、请求次数、响应次数、完成原因等。
在这里插入图片描述

保存到文件

运行完Scrapy后,我们只在控制台看到了输出结果。要完成保存结果,不需要额外的代码,Scrapy提供的Feed Exports可以轻松将抓取结果输出。例如,我们想将上面的结果保存成JSON文件,可以执行如下命令:

scrapy crawl quotes -o quotes.json

命令运行后,项目内多了一个quotes.json文件,文件包含了刚才抓取的所有内容,内容是JSON格式。
另外我们还可以每一个Item输出一行JSON,输出后缀为jl,为jsonline的缩写,命令如下所示:

scrapy crawl quotes -o quotes.jl

scrapy crawl quotes -o quotes.jsonlines

输出格式还支持很多种,例如csv、xml、pickle、marshal格式以及ftp远程输出:

scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o quotes.marshal
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv

其中,ftp输出需要正确配置用户名、密码、地址、输出路径,否则会报错。
通过Scrapy提供的Feed Exports,我们可以轻松地输出抓取结果到文件。对于一些小型项目来说,这应该足够了。不过如果想要更复杂的输出,如输出到数据库等,我们可以使用Item Pileline来完成。

使用Item Pipeline

如果想进行更复杂的操作,如将结果保存到MongoDB数据库,护着筛选某些有用的Item,则我们可以定义Item Pipeline来实现。
Item Pipeline为项目管道。当Item生成后,它会自动被送到Item Pipeline进行处理,我们常用Item Pipeline来做如下操作。

  • 清理HTML数据。
  • 验证爬取数据,检查爬取字段。
  • 查重并丢弃重复内容。
  • 将爬取结果保存到数据库。

要实现Item Pipeline很简单,只需要定义一个类并实现process_item()方法即可。启用Item Pipeline后,Item Pipeline会自动调用这个方法。process_item()方法必须返回包含数据的字典或Item对象,或者抛出DropItem异常。
porcess_item()方法有两个参数。一个参数是item,每次Spider生成的Item都会作为参数传递过来。另一个参数是spider,就是Spider的实例。
接线来,我们实现一个Item Pipeline,筛掉text长度大于50的Item,并将结果保存到MongoDB。
修改项目里的pipelines.py文件,之前用命令行自动生成的文件内容可以删掉,增加一个TextPipeline类,内容如下:

from scrapy.exceptions import DropItem

class TextPipeline(object):
	def __init__(self):
		self.limit = 50
	
	def process_item(self, item, spider):
		if item['text']:
			if len(item['text']) > self.limit:
				item['text'] = item['text'][0:self.limit].rstrip() + '...'
			return item
		else:
			return DropItem('Missing Text')

这段代码在构造方法里定义了限制长度为50,实现了process_item()方法,其参数是item和spider。首先该方法判断item的text属性是否存在,如果不存在,则抛出DropItem异常;如果存在,再判断长度是否大于50,如果大于,那就截断然后拼接省略号,再将item返回即可。
接下来,我们将处理后的item存入MongoDB,定义另一个Pipeline。同样在pipelines.py中,我们实现另一个类MongoPipeline,内容如下:

import pymongo

class MongoPipeline(object):
	def __init__(self, mongo_uri, mongo_db):
		self.mongo_uri = mongo_uri
		self.mongo_db = mongo_db
		
	@classmethod
	def from_crawler(cls, crawler):
		return cls(
			mongo_uri = crawler.settings.get('MONGO_URI'),
			mongo_db = crawler.settings.get('MONGO_DB')
		)
		
	def open_spider(self, spider):
		self.client = pymongo.MongoClient(self.mongo_uri)
		self.db = self.client[self.mongo_db]
		
	def process_item(self, item, spider):
		name = item.__class__.__name__
		self.db[name].insert(dict(item))
		return item
		
	def close_spider(self, spider):
		self.client.close()

MongoPipeline类实现了API定义的另外几个方法:

  • from_crawler。它是一个类方法,用@classmethod标识,是一种依赖注入的方式。它的参数就是crawler,通过crawler我们可以拿到全局配置的每个配置信息。在全局配置settings.py中,我们可以定义MONGO_URI和MONGO_DB来指定MongoDB连接需要的地址和数据库名称,拿到配置信息之后返回类对象即可。所以这个方法的定义主要是用来获取settings.py中的配置的。
  • open_spider。当Spider开启时,这个方法被调用。上文程序中主要进行了一些初始化操作。
  • close_spider。当Spider关闭时,这个方法会调用。上文程序中将数据库连接关闭。

最主要的process_item()方法则执行了数据插入操作。
定义好TextPipeline和MongoPipeline这两个类后,我们需要再settings.py中使用它们。MongoDB的连接信息还需要定义。
我们在settings.py中加入如下内容:

ITEM_PIPELINES = {
	'tutorial.pipelines.TextPipeline':300,
	'tutorial.pipelines.MongoPipeline':400,
}
MONGO_URI = 'localhost'
MONGO_DB = 'tutorial'

赋值ITEM_PIPELINES字典,键名是Pipeline的类名称,键值是调用优先级,是一个数字,数字越小赌赢的Pipeline越先被调用。
再重新执行爬取,命令如下所示:

scrapy crawl quotes

爬取结束后,MongoDB中穿件了一个tutorial的数据库、QuoteItem的表,如图所示:
在这里插入图片描述
长的text已经被处理并追加省略号,短的text保持不变,author和tags也都相应保存。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值