美文网首页
scrapy抓取百度图片-写给自己看爬虫系列1

scrapy抓取百度图片-写给自己看爬虫系列1

作者: wfishj | 来源:发表于2017-10-14 23:04 被阅读0次

    前言

    需求:用scrapy抓取图片
    思路:scrapy抓取图片的逻辑是,用爬虫抓取图片url输出到pipeline中,然后由pipeline实施下载保存。关于pipeline的编写,可以自定义一个pipeline或者继承scrapy的imagespipeline从而实现抓取图片,本文以百度图片为例子写一个下载图片的爬虫。

    百度图片爬虫-item说明
    import scrapy
    from scrapy import Field,Item
    
    class PicItem(scrapy.Item):
        search_word = Field()  #搜索的关键词
        pic_name  = Field()  #图片名字
        pic_url = Field()       #图片url
    
    百度图片爬虫-spider说明
    import scrapy,json
    from scrapy.http import Request
    from scrapy.http import FormRequest
    from pic.items import PicItem
    
    class PicspiderSpider(scrapy.Spider):
        
        name = "picspider"
        
        allowed_domains = ["http://image.baidu.com/"]
        
        start_urls = ["http://image.baidu.com"]
    
        def parse(self, response):
    
            search_word   = '美女'    #查找词
            
            baidu_pic_url = "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word={0}&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn=60&rn=30&gsm=3c&1507915209449=".format(search_word)  #百度图片url
            
            yield Request(baidu_pic_url,meta={"search_word":search_word},callback=self.get_pic,dont_filter=True)
        
        def get_pic(self,response):
            
            item = PicItem()
     
            response_json = response.text    #返回的数据是json格式
     
            response_dict = json.loads(response_json)  #转化为字典
     
            response_dict_data = response_dict['data']  #图片的有效数据在data参数中
            
            for pic in response_dict_data:
    
                if pic:
                    item['search_word']    = response.meta['search_word']  #搜索关键词赋值
                    item['pic_url']        = pic['middleURL']  #百度图片搜索结果url            
                    item['name']           = pic['fromPageTitleEnc']  #百度图片搜索结果对应的title            
                    yield item
    
    

    自定义pipeline写法


    pipeline写法

    对爬虫输出的url地址进行请求并且用with open方式存储图片,存储路径为在当前项目中的对应搜索词目录下,图片文件名以百度图片上的图片标题命名。最后在setings中设置好pipeline即可。

    import requests,os, sys
    from pic import settings       #从settings中导入设定的参数
    from scrapy.exceptions import DropItem
    from scrapy.http import Request
    
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
     class PicPipeline(object):
    
         def process_item(self, item, spider):
            
             dir_path = item["search_word"]  
    
             if not os.path.exists(dir_path):    #检查搜索词是否已经有对应的文件夹,若没则创建一个
                
                 os.makedirs(dir_path)
    
             pic_name = item['name']
    
             pic_url  = item['pic_url']
    
             pic_path = dir_path+'/'+pic_name+'.jpg'   #最终路径为搜索词+图片标题
    
             pic  = requests.get(pic_url,headers=settings.HEADER)  #对图片url发出请求
    
             with open(pic_path,'wb') as file:   #使用wb方式保存图片
    
                 file.write(pic.content)
    

    继承imagespipeline类写法


    imagespipeline工作流程

    1.爬取一个Item,将图片的URLs放入image_urls字段
    2.从Spider返回的Item,传递到Item Pipeline
    3.当Item传递到ImagePipeline,将调用Scrapy 调度器和下载器完成image_urls中的url的调度和下载。ImagePipeline会自动高优先级抓取这些url,于此同时,item会被锁定直到图片抓取完毕才被解锁。
    4.图片下载成功结束后,图片下载路径、url和校验和等信息会被填充到images字段中。


    setting中的常用属性
    ITEM_PIPELINES = ['pic.pipelines. PicPipeline']
    IMAGES_STORE = '\home\xiaoming\web_robot\project'  #保存路径
    IMAGES_EXPIRES = 90   #过期天数
    IMAGES_MIN_HEIGHT = 0  #图片最小的高度,小于该值会被过滤
    IMAGES_MIN_WIDTH   =0   #图片最小的宽度,小于该值会被过滤
    

    imagespipeline写法
    import requests,os
    from pic import settings
    
    import sys  
    from scrapy.contrib.pipeline.images import ImagesPipeline  #导入images中间件模块
    from scrapy.http import Request
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    
    class PicPipeline(ImagesPipeline): #继承imagespipeline
        
        def get_media_requests(self,item,info):
            
            url = item['pic_url']
    
            yield Request(url)
    
        def item_completed(self,results,item,info):
            # result是一个二元组列表,第一个参数为下载是否成功,第二个参数是详细信息。url,path等数据
            image_path = [ result['path'] for exist,result in results if ok ] 
    

    参考文章
    scrapy 下载图片 ImagesPipeline
    Python:使用Scrapy框架的ImagesPipeline下载图片如何保持原图片名称呢?

    相关文章

      网友评论

          本文标题:scrapy抓取百度图片-写给自己看爬虫系列1

          本文链接:https://www.haomeiwen.com/subject/suofuxtx.html