Scrapy框架(四):Item Pipeline的用法

当Spider解析完Response之后,Item就会传递到Item Pipeline,被定义的Item Pipeline组件会顺次调用,完成一连串的处理过程。

1.核心方法

process_item(item,spider)

这个是必须要实现的方法,被定义的Item Pipeline会默认调用这个方法对Item进行处理。

open_spider(spider)

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

close_spider(spider)

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

from_crawler(cls,crawler)

是一个类方法,用@classmethod标识,是一种依赖注入的方式。它的参数是crawler,通过crawler对象,我们可以拿到Scrapy的所有核心组件,如全局配置的每个信息,然后创建一个Pipeline实例,参数cls就是class,最后返回一个class实例。

实战练习:抓取360摄影美图

扫描二维码关注公众号,回复: 5783650 查看本文章

一、构造请求

在settings.py里面定义一个变量MAX_PAGE

在Spider中定义start_request()方法

    def start_requests(self):
        data = {'ch': 'photography', 'listtype': 'new'}
        base_url = 'https://image.so.com/zj?'
        for page in range (1, self.settings.get ('MAX_PAGE') + 1):
            data['sn'] = page * 30
            params = urlencode (data)
            url = base_url + params
            yield Request (url, self.parse)

修改settings.py中的ROBOTSTXT_OBEY变量,将其设置为False

二、提取信息

在Item中定义一个ImageItem

from scrapy import Item,Field

class ImageItem(Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    collection = table = 'images'
    id = Field()
    url = Field()
    title = Field()
    thumb = Field()

接下来提取Spider里有关信息,将Spider里的parse()方法该写

    def parse(self, response):
        result = json.loads(response.text)
        for image in result.get('list'):

            item = ImageItem()
            item['id'] = image.get('imageid')
            item['url'] = image.get('qhimg_url')
            item['title'] = image.get('group_title')
            item['thumb'] = image.get('qhimg_thumb_url')
            yield item

三、存储信息到数据库

新建一个数据库——images360,新建一个数据表——images

实现一个MySQLPipeline

class MysqlPipeline():
    def __init__(self,host,database,user,password,port):
        self.host = host
        self.database = database
        self.user = user
        self.password = password
        self.port = port


    @classmethod
    def from_crawler(cls,crawler):
        return cls(
            host=crawler.settings.get('MYSQL_HOST'),
            database=crawler.settings.get ('MYSQL_DATABASE'),
            user=crawler.settings.get ('MYSQL_USER'),
            password=crawler.settings.get ('MYSQL_PASSWORD'),
            port=crawler.settings.get ('MYSQL_PORT'),
        )

    def open_spider(self,spider):
        self.db = pymysql.connect(self.host,self.user,self.password,self.database,charset='utf8',port=self.port)
        self.cursor = self.db.cursor()

    def close_spider(self,spider):
        self.db.close()

    def process_item(self,item,spider):
        data = dict(item)
        keys = ','.join(data.keys())
        values = ','.join(['%s']*len(data))
        sql = 'insert into %s (%s) values (%s)' % (item.table,keys,values)
        self.cursor.execute(sql,tuple(data.values()))
        self.db.commit()
        return item

在settings.py里添加数据库相关变量

MYSQL_HOST = 'localhost'
MYSQL_DATABASE = 'images360'
MYSQL_PORT = 3306
MYSQL_USER = 'root'
MYSQL_PASSWORD = 'root'

四、下载图片到本地

Scrapy提供了专门处理下载的Pipeline,包括文件下载和图片下载

首先定义存储文件的路径,在settings.py中添加IMAGES_STORE

IMAGES_STORE = './images'     #我们将路径定义为当前路径下的images子文件夹,即下载的图片都会保存到本项目的images文件夹中。

自定义ImagePipeline,继承内置的ImagesPipeline,重写几个方法

class ImagePipeline(ImagesPipeline):
    def file_path(self, request, response=None, info=None):
        url = request.url
        file_name = url.split('/')[-1]
        return file_name

    def item_completed(self, results, item, info):
        image_paths = [x['path'] for ok,x in results if ok]
        if not image_paths:
            raise DropItem('Image Downloaded Failed')
        return item

    def get_media_requests(self, item, info):
        yield Request(item['url'])

五、修改settings.py,设置ITEM_PIPELINES

ITEM_PIPELINES = {
    'images360.pipelines.ImagePipeline': 300,
    'images360.pipelines.MysqlPipeline': 301,
}

猜你喜欢

转载自blog.csdn.net/Mai_Dreizehn/article/details/86528773
今日推荐