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

前言

需求:用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下载图片如何保持原图片名称呢?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容