学习 scrapy 中 spider 和 item pipeline 的用法,主要介绍一些方法的使用。🍇点击此处查看原文。
spider
name
每个spider都有自己的名字,这个名字必须唯一,这样我们才能指定运行我们的spider。命名没什么要求,不过尽力要直接体现spider,比如爬取taobao.com,那我们就取名taobao。
start_urls
爬虫起始列表。这里保存的都是待爬取的URL。
allowed_domains
用来定义允许爬虫爬取的取名。例如在爬取淘宝过程中爬取到其他域名非taobao.com,那么就跳过。这个选项是可选的。
custom_settings
先声明这个为字典格式。spider中有一些特殊的配置信息可以使用这个属性,设置以后在运行spider会直接使用custom_settings配置的信息,跳过检查配置文件。
from_crawler()
我们利用这个方法获取爬虫的配置信息,例如在上一节讲到的:
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
)
这个在获取配置信息的时候经常用到。
start_requests()
这个方法必须返回一个可迭代对象。该对象包含了spider用于爬取的第一个Request。我们可以在参数中定义URL,method,callback等信息。
make_requests_from_url(url)
该方法接受一个URL并返回用于爬取的Request对象。该方法在初始化request时被start_requests()调用,也被用于转化url为request。
logger
用来输出日志,例如输出访问网页的状态码: logger.info(response.status)
在输出日志中会体现URL的状态码。
parse
默认回调函数,如果我们在使用过程中没有特殊规定,都是使用这个方法来解析网页。
closed
当spider关闭时,该函数被调用。例如我们在结束爬虫时要断开与数据库的链接,我们就可以使用这个方法。也可以在运行结束后提示我们已经运行完成。
这些就是spider中常用的方法和属性,读者们可以按需使用,详细内容可以阅读官方文档——spider用法。
Item Pipline
Item Pipline 有很多用处,官方文档举了一些常用的例子。
- cleansing HTML data
- validating scraped data (checking that the items contain certain fields)
- checking for duplicates (and dropping them)
- storing the scraped item in a database
有了这个组件在实际过程中对数据的处理还是很方便的。接下来我们学习编写自己的item pipeline。
process_item(self, item, spider)
每个 item pipeline 组件都需要调用该方法,这个方法必须返回一个 Item (或任何继承类)对象, 或是抛出 DropItem 异常,被丢弃的 item 将不会被之后的 pipeline 组件所处理。
open_spider(self, spider)
当 spider 被开启时,这个方法被调用。
close_spider(spider)
当 spider 被关闭时,这个方法被调用
from_crawler(cls, crawler)
这个类方法,主要用来获取scrapy项目中的配置信息。
Item pipeline 例子
举了两个常用的例子,一般来说够用了,官方文档还有其他例子。
爬虫获取到item进行操作。
首先判断item的price属性是否存在,如果存在就进行下一步操作,如果不存在就抛出异常。
from scrapy.exceptions import DropItem
class PricePipeline(object):
vat_factor = 1.15
def process_item(self, item, spider):
if item['price']:
if item['price_excludes_vat']:
item['price'] = item['price'] * self.vat_factor
return item
else:
raise DropItem("Missing price in %s" % item)
去重
这个例子是一个可以去重的过滤器,丢弃那些已经被处理过的item。我们的item有唯一id,但是返回内容中有许多相同id:
from scrapy.exceptions import DropItem
class DuplicatesPipeline(object):
def __init__(self):
self.ids_seen = set()
def process_item(self, item, spider):
if item['id'] in self.ids_seen:
raise DropItem("Duplicate item found: %s" % item)
else:
self.ids_seen.add(item['id'])
return item
先定义一个集合,如果id已经存在就删除,如果不存在就添加到集合中。
保存到mongo数据库
import pymongo
class MongoPipeline(object):
collection_name = 'scrapy_items'
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_DATABASE', 'items')
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def close_spider(self, spider):
self.client.close()
def process_item(self, item, spider):
self.db[self.collection_name].insert_one(dict(item))
return item
这段代码利用from_crawler
方法获取settings中的配置信息,在spider开启时连接到数据库,在spider关闭时间断开与数据库的连接,在执行pipline过程中将item保存到数据库中。
配置 item pipline
在settings中找到ITEM_PIPELINES
属性,写入类的名称和优先级。
ITEM_PIPELINES = {
'myproject.pipelines.PricePipeline': 300,
'myproject.pipelines.MongoPipeline': 400,
}
数值越小优先级越高,要注意数值的范围是0~1000。