imagespipeline是scrapy自带的类,用来处理图片(爬取时将图片下载到本地)用的。
优势:
将下载图片转换成通用的jpg和rgb格式
避免重复下载
缩略图生成
图片大小过滤
异步下载
......
工作流程:
爬取一个item,将图片的urls放入image_urls字段
从spider返回的item,传递到item pipeline
当item传递到imagepipeline,将调用scrapy 调度器和下载器完成image_urls中的url的调度和下载。
图片下载成功结束后,图片下载路径、url和校验和等信息会被填充到images字段中。
实现方式:
自定义pipeline,优势在于可以重写imagepipeline类中的实现方法,可以根据情况对照片进行分类;
直接使用imagepipeline类,简单但不够灵活;所有的图片都是保存在full文件夹下,不能进行分类
实践:爬取http://699pic.com/image/1/这个网页下的前四个图片集(好进行分类演示)
这里使用方法一进行实现:
步骤一:建立项目与爬虫
1.创建工程:scrapy startproject xxx(工程名)
2.创建爬虫:进去到上一步创建的目录下:scrapy genspider xxx(爬虫名) xxx(域名)
步骤二:创建start.py
1 from scrapy import cmdline
2
3 cmdline.execute("scrapy crawl 699pic(爬虫名)".split(" "))
步骤三:设置settings
1.关闭机器人协议,改成false
2.设置headers
3.打开item_pipelines
将项目自动生成的pipelines注释掉,黄色部分是下面步骤中自己写的pipeline,这里先不写。
步骤四:item
1 class img699picitem(scrapy.item):
2 # 分类的标题
3 category=scrapy.field()
4 # 存放图片地址
5 image_urls=scrapy.field()
6 # 下载成功后返回有关images的一些相关信息
7 images=scrapy.field()
步骤五:写spider
import scrapy
from ..items import img699picitem
import requests
from lxml import etree
class a699picspider(scrapy.spider):
name = '699pic'
allowed_domains = ['699pic.com']
start_urls = ['http://699pic.com/image/1/']
headers={
'user-agent':'mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/67.0.3396.62 safari/537.36'
}
def parse(self, response):
divs=response.xpath("//div[@class='special-list clearfix']/div")[0:4]
for div in divs:
category=div.xpath("./a[@class='special-list-title']//text()").get().strip()
url=div.xpath("./a[@class='special-list-title']/@href").get().strip()
image_urls=self.parse_url(url)
item=img699picitem(category=category,image_urls=image_urls)
yield item
def parse_url(self,url):
response=requests.get(url=url,headers=self.headers)
htmlelement=etree.html(response.text)
image_urls=htmlelement.xpath("//div[@class='imgshow clearfix']//div[@class='list']/a/img/@src")
return image_urls
步骤六:pipelines
import os
from scrapy.pipelines.images import imagespipeline
from . import settings
class img699picpipeline(object):
def process_item(self, item, spider):
return item
class images699pipeline(imagespipeline):
def get_media_requests(self, item, info):
# 这个方法是在发送下载请求之前调用的,其实这个方法本身就是去发送下载请求的
request_objs=super(images699pipeline, self).get_media_requests(item,info)
for request_obj in request_objs:
request_obj.item=item
return request_objs
def file_path(self, request, response=none, info=none):
# 这个方法是在图片将要被存储的时候调用,来获取这个图片存储的路径
path=super(images699pipeline, self).file_path(request,response,info)
category=request.item.get('category')
image_store=settings.images_store
category_path=os.path.join(image_store,category)
if not os.path.exists(category_path):
os.makedirs(category_path)
image_name=path.replace("full/","")
image_path=os.path.join(category_path,image_name)
return image_path
步骤七:返回到settings中
1.将黄色部分填上
2.存放图片的总路径
images_store=os.path.join(os.path.dirname(os.path.dirname(__file__)),'images')
最终结果:
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!