Scrapy(四)Item Pipeline 的使用

介绍

Item Pipeline 即项目管道,它的调用发生在Spider 产生Item之后,当Spider解析完Response,Item就会被Engine传递到Item Pipeline,被定义的
Item Pipeline 组件会顺次被调用。完成一连串的处理过程。比如数据清洗,存储等。
Item Pipeline的主要功能如下:

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

核心方法

我们可以自定义Item Pipeline,只需要实现指定的方法就好,其中必须实现的一个方法是:

process_item(item,spider)

另外还有几个比较实用的方法,它们是:

  • open_spider(spider)
  • close_spider(spider)
  • from_crawler(cls,crawler)

process_item(item,spider)

被定义的Item Pipeline 会默认调用这个方法对Item进行处理,比如进行数据处理或者将数据写入数据库等操作。process_item 方法必须返回Item类型的值
或者抛出DropItem异常

  • 如果返回的是Item对象,那么此Item 会接着被低优先级的process_item方法处理,知道所有方法被调用完毕
  • 如果抛出DropItem异常。那么此Item就会被丢弃,不再进行处理

open_spider(self,spider)

该方法是在Spider开启的时候被自动调用的,在这里我们可以做一些初始化操作,如开启数据库连接等等。

close_spider(spider)

close_spider方法是在Spider 关闭的时候自动调用的,在这里可以做一些收尾的工作,如关闭数据库的连接等等

from_crawler(cls,crawler)

from_crawler 是一个类方法,它接收一个crawler参数。通过crawler对象,我们可以拿到Scrapy的所有核心组件。如全局配置的每个信息
然后可以在这个方法里面创建一个Pipeline实例。参数cls就是当前类对象,最后返回一个当前Pipeline 实例

实战

items.py:

from scrapy import Item,Field


class MoveItem(Item):
    name = Field()
    categories = Field()
    score = Field()
    drama = Field()
    directors = Field()
    actors = Field()

scrape.py:

import scrapy
from scrapy.http import Request
from scrapyitempipelinedemo.items import MoveItem


class ScrapeSpider(scrapy.Spider):
    name = 'scrape'
    allowed_domains = ['ssr1.scrape.center']
    base_url  = 'https://ssr1.scrape.center/'
    max_page = 10

    def start_requests(self):
        for i in range(1,self.max_page + 1):
            url  = f'{self.base_url}page/{i}'
            yield Request(url, callback=self.parse_first)

    # def parse(self, response):
    #     print(response.text)

    def parse_first(self,response):
        '''
        解析每页数据 - 每个商品的URL
        :param response:
        :return:
        '''
        for item in response.css('.item'):
            href = item.css('.name::attr(href)').extract_first()
            url = response.urljoin(href)
            yield Request(url, callback=self.parse_detail)



    def parse_detail(self,response):
        movie_item = MoveItem()
        # print(f'电影名称:{response.css(".m-b-sm::text").extract_first()}')
        # print(f'电影名称:{response.xpath("//div/a/h2/text()").extract_first()}')
        movie_item['name'] = response.xpath("//div/a/h2/text()").extract_first()
        movie_item['categories'] = response.xpath("//div/button/span/text()").extract()
        movie_item['score'] = response.css('.score::text').extract_first().strip()
        # print(response.css('.score::text').extract_first())
        # movie_item['drama'] = response.xpath("//div[@class='drama']/p/text()").extract_first().strip() # 电影描述
        movie_item['drama']  = response.css('.drama p::text').extract_first().strip()
        movie_item['directors'] = [] # 导演
        movie_item['actors'] = []  # 演员

        # 导演图片
        director_img = response.css('.director .image::attr(src)').extract()
        director_name = response.css('.director .name::text').extract()
        for name,img in list(zip(director_name, director_img)):
            movie_item['directors'].append({
                'name':name,
                'img':img
            })

        # 演员
        actor_img = response.css('.actor .image::attr(src)').extract()
        actor_name = response.css('.director .name::text').extract()
        for name,img in zip(actor_name, actor_img):
            movie_item['actors'].append({
                'name':name,
                'img':img
            })
        yield movie_item

输出:

{'actors': [{'img': 'https://p0.meituan.net/movie/5cbe849bb17c8966a423ee015dc21aca41689.jpg@128w_170h_1e_1c',
             'name': '李力持'},
            {'img': 'https://p1.meituan.net/movie/7a8ec6da5a8612a25519550806545b2e52391.jpg@128w_170h_1e_1c',
             'name': '周星驰'}],
 'categories': ['剧情', '喜剧', '爱情'],
 'directors': [{'img': 'https://p1.meituan.net/movie/7c6f180a06f744aee95ab3b8bef29c2633555.jpg@128w_170h_1e_1c',
                'name': '李力持'},
               {'img': 'https://p0.meituan.net/movie/5cbe849bb17c8966a423ee015dc21aca41689.jpg@128w_170h_1e_1c',
                'name': '周星驰'}],
 'drama': '尹天仇(周星驰 '
          '饰)一直醉心戏剧,想成为一名演员,平时除了做跑龙套以外,还会在街坊福利会里开设演员训练班。此时舞小姐柳飘飘在妈妈桑的带领下来到这里要求学做戏,原来柳飘飘 
有一段非常不愉快的经历,在尹天仇对她指导的过程中,柳飘飘对尹天仇渐生情愫,同时她也成为了夜总会里当红的小姐。尹天仇受到了极多白眼之后,终于得到了大明星鹃姐(莫文蔚 '
          '饰)的赏识,提携他担演新戏中的男主角,但没想到突然把他的角色换掉了,令他失望不已。在片场当场务的卧底警员(吴孟达 '
          '饰)身份被识穿,尹天仇阴差阳错的帮忙破了案。之后尹天仇继续活跃在街坊福利会的演员训练班里。',
 'name': '喜剧之王 - The King of Comedy',
 'score': '9.5'}

后续可实现 Pipeline 将数据保存在mongodb,详情参见:https://www.cnblogs.com/czzz/p/16949509.html#item-pipeline-将数据保存到mongodb

posted @ 2022-12-20 20:03  chuangzhou  阅读(195)  评论(0编辑  收藏  举报