Scrapy的项目管道

人生苦短,我用Python

Item管道(Item Pipeline)

  • 主要负责处理由蜘蛛从网页抽取的Item,主要任务是清洗、验证和存储数据。
  • 当页面被蜘蛛解析后,将被发送到Item管道,并经过几个特定的次序处理数据。
  • 每个Item管道的组件都是由一个简单的方法组成的Python类。
  • 它们获取了Item并执行它们的方法,同时还需要确定是否需要在Item管道中继续执行下一步或是直接丢弃掉不处理。

Item管道的作用:

  • 清理HTML数据
  • 验证抓取的数据(检查项目是否包含特定字段)
  • 检查重复(并删除)--说明:由于性能原因,去重最好在链接中去重,或者利用数据库主键的唯一性去重
  • 将抓取的项目存储在数据库中

Item管道主要函数:

1. process_item(self, item, spider)------必须实现

每个Item Pipeline组件都需要调用该方法,这个方法必须返回一个Item(或任何继承对象)对象,或是抛出DropItem异常,被丢弃的item将不会被之后的Pipeline组件所处理


需传入的参数:

  • item(Item对象):被爬取的Item
  • spider(Spider对象):爬取该item的spider


该方法会被每一个item pipeline组件所调用,process_item必须返回以下其中的任意一个对象;

  • 一个字典dict
  • 一个Item对象或者它的子类对象
  • 一个Twisted Deferred对象
  • 一个DropItem Exception;如果返回此异常,则该item将不会被后续的item pipeline继续访问

特别注意:该方法是Item Pipeline必须实现的方法,其他三个方法(open_spider/close_spider/from_crawler)是可选的方法

2.open_spider(self, spider) —— 非必需,为爬虫启动的时候调用;

当 spider 被开启时,这个方法被调用。可以实现在爬虫开启时需要进行的操作,比如说打开一个待写入的文件,或者连接数据库等

需要传入的参数:

  • spider (Spider 对象) : 被开启的 spider


3. close_spider(self, spider) —— 非必需, 为爬虫关闭的时候调用;

当 spider 被关闭时,这个方法被调用。可以实现在爬虫关闭时需要进行的操作,比如说关闭已经写好的文件,或者关闭与数据库的连接

需要传入的参数:

  • spider (Spider 对象) : 被关闭的 spider


4. from_crawler(cls, crawler) —— 非必需,也是在启动的时候调用,比 open_spider早。

该类方法用来从 Crawler 中初始化得到一个 pipeline 实例;它必须返回一个新的 pipeline 实例;Crawler 对象提供了访问所有 Scrapy 核心组件的接口,包括 settings 和 signals

需要传入的参数:

  • crawler (Crawler 对象) : 使用该管道的crawler


项目案例:爬取58同城房屋出租信息

代码如下:

items.py:定义我们所要爬取的信息的相关属性,此例中需要爬取的是name、price、url

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class City58Item(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()
    price=scrapy.Field()
    url=scrapy.Field()
    pass复制代码

city58_demo.py:主要是用于定义请求链接,并使用pyquery选取目标元素

# -*- coding: utf-8 -*-
import scrapy
from pyquery import PyQuery
from ..items import City58Item
import time
from scrapy.http import Request

class City58DemoSpider(scrapy.Spider):
    name = 'city58_demo'
    allowed_domains = ['58.com']
    start_urls = ['http://sh.58.com/chuzu/']

    def parse(self, response):
        for index in range(1,4):
            url='http://sh.58.com/chuzu/pn{0}'.format(str(index))
            print(url)
            time.sleep(3)
            yield Request(url=url,callback=self.page)

    def page(self,response):
        jpy = PyQuery(response.text)
        li_list=jpy('body > div.mainbox > div.main > div.content > div.listBox > ul > li').items()
        for it in li_list:
            a_tag = it(' div.des > h2 > a')
            item = City58Item()
            item['name'] = a_tag.text()  # a_tag取出文本
            item['url'] = a_tag.attr('href')  # 取出href参数
            item['price'] = it('div.listliright > div.money > b').text()
            yield item  # 把Item返回给引擎复制代码

pipeline.py:当item数据被city58_test爬虫爬取好并返回给引擎以后,引擎会把item交给City58Pipeline这个管道处理。这个pipeline文件负责打开MongoDB数据库,并将数据写入数据库:

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
import pymongo

class City58Pipeline(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('localhost:27017'),
            mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
        )
    def open_spider(self,spider):
        #self.file=open('58_chuzu.txt','w',encoding='utf8')
        self.client=pymongo.MongoClient()
        self.db=self.client[self.mongo_db]
        print('打开数据库了')
    def process_item(self, item, spider):
        line='{}\n'.format(json.dumps(dict(item)))#把item转换成字符串
        #self.file.write(line)
        self.db[self.collection_name].insert_one(dict(item))
        return item
    def close_spider(self,spider):
        #self.file.close()
        self.client.close()
        print('关闭数据库了')复制代码

settings.py:开启City58Pipeline这个管道

说明:300相当于一个执行优先级的序号

运行爬虫,可以在项目下创建一个文件:

执行该文件即可执行爬虫:

和使用命令行scrapy crawl city58_demo效果是一样的。

最后执行结果如图这样的数据。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值