zoukankan      html  css  js  c++  java
  • Scrapy实战篇(六)之爬取360图片数据和图片

      

      本篇文章我们以360图片为例,介绍scrapy框架的使用以及图片数据的下载。

      目标网站:http://images.so.com/z?ch=photography

      思路:分析目标网站为ajax加载方式,通过构造目标url从而请求数据,将图片数据存储在本地,将图片的属性存储在mongodb中。

      1、首先定义我们需要抓取的字段

    class ImageItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        collection = 'images'  #代表mongodb的的集合名称
        #下面四个字段分别是图片id,链接,标题,缩率图
        id = Field()
        url = Field()
        title = Field()
        thumb = Field()

      

      2、构造我们要爬取的url;由于目标网站时ajax加载的,展示的数据在http://images.so.com/zj?ch=photography&sn=30&listtype=new&temp=1中以json的形式存储,不断的下拉页面之后,每次变化的参数只有sn,并且每次以30的增量增加,第一页sn=30,第二页为60,则sn和页码的关系为sn*30,所以我们可以构造出url

    #定义起始需要爬取的url列表,首先从spider中发送给调度引擎
        def start_requests(self):
            data = {'ch':'photography','listtype':'new','temp':1}
            base_url = 'http://images.so.com/zj?'
            for page in range(1,self.settings.get('MAX_PAGE') + 1):   #MAX_PAGE以参数的形式在settings文件中配置
                data['sn'] = page * 30
                url = base_url + urlencode(data)
                yield Request(url,self.parse)

      3、编写解析函数,返回的数据是json格式

    #解析函数
        def parse(self, response):
            result = json.loads(response.text)   #将JSON文本字符串转为JSON对象
            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

      4、编写pipeline文件,将图片属性数据存入mongo,将图片存储到本地

    import pymongofrom scrapy import Request
    from scrapy.exceptions import DropItem
    from scrapy.pipelines.images import ImagesPipeline
    
    
    #定义了两个个Pipeline,分别为数据存储到mongodb,图片下载到本地
    #在settings中定义Pipeline的执行顺序
    class MongoPipeline(object):
        def __init__(self,mongo_url,mongo_db):
            self.mongo_url = mongo_url
            self.mongo_db = mongo_db
    
        @classmethod
        def from_crawler(cls,crawler):
            return cls(
                mongo_url=crawler.settings.get('MONGO_URL'),
                mongo_db=crawler.settings.get('MONGO_DB')
            )
    
        def open_spider(self,spider):
            self.client = pymongo.MongoClient(self.mongo_url)
            self.db = self.client[self.mongo_db]
    
        def process_item(self, item, spider):
            self.db[item.collection].insert(dict(item))
            return item
    
        def close(self,spider):
            self.client.close()

    class ImagesPipeline(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 Download Failed') return item def get_media_requests(self,item,info): yield Request(item['url'])

    第一个为MongoPipeline,通过类方法from_crawler从settings文件中获取mongodb的配置信息,将蜘蛛文件中返回的item存入mongo数据库。

    第二个为ImagesPipeline,scrapy提供了专门处理下载的Pipeline,包括文件下载和图片下载,下载过程支持异步和多线程,效率极高。

    首先定义存储文件的路径,需要定义一个IMAGES_STORE变量,在settings文件中添加一行

    IMAGES_STORE = './images

    我们将路径定义在当前路径下的images中,即下载的图片都会存储在这个文件夹中。

      内置的ImagesPipeline会默认读取Item对象的image_urls字段,并认为该变量是一个列表,会遍历这个字段,然后取出url进行图片下载。

      但是我们上面定义的模型可以看出,Item对象的图片连接并不是image_url,也不是列表形式的,而是单个url,所以为了实现下载,需要重写ImagePipeline,继承内置的ImagePileline,再次我们重写了三个方法,分别是

      1)get_media_requests():它的第一个参数item就是爬取生成的Item对象,我们将它的url取出来,直接生成Request对象返回,从而加入调度队列,等待被调度,执行下载。

      2)file_path():它的第一个参数request就是当前下载的Request对象,这个方法用来返回保存的文件名称,直接将图片链接的最后一部分当做文件名称即可。

      3)item_completed():它是当单个Item完成下载时的处理方法,因为并不是每张图片都会下载成功,所以需要分析下载结果并剔除下载失败的图片,该方法的第一个参数results就是该item对象的下载结果,它是一个列表的形式,列表的每一个元素都是一个元组,其中包含了下载成功或者失败的信息。

      5、在settings中激活pipeline,并配置需要的配置项

    ITEM_PIPELINES = {
       'images360.pipelines.ImagesPipeline': 300,
       'images360.pipelines.MongoPipeline': 301,
    }

      6、执行爬虫,获取数据即可。

      scrapy crawl  images

      项目完整代码:https://gitee.com/liangxinbin/Scrpay/tree/master/images360

  • 相关阅读:
    async简单使用
    node调用phantomjs-node爬取复杂页面
    mongodb3 ubuntu离线安装(非apt-get)及用户管理
    2040-亲和数(java)
    JavaScript闭包简单理解
    nodejs构建多房间简易聊天室
    linux下安装nodejs及npm
    EventBus轻松使用
    mysql用户创建及授权
    python中json的基本使用
  • 原文地址:https://www.cnblogs.com/lxbmaomao/p/10372065.html
Copyright © 2011-2022 走看看