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
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/16994998.html

                
            
        
浙公网安备 33010602011771号