spider.py
- 导入用于保存图片下载信息的item类.
- 在爬虫类中解析图片url,并保存在列表中,根据需要提取标题等其它信息
- 返回赋值后的item类
import scrapy
from ..items import ImageItem
class MySpider(Spider):
def parse(self,response):
titles = response.xpath('xxxxxxxxx') #list,获取网页标题
title = ''.join(titles).strip() #str,去除网页(共同)标题中的空白字符
imageUrls = response.xpath('xxxxxxxx') #list,获取图片链接列表
item = ImageItem(title = title,image_urls = imageUrls)
yield item
items.py
定义一个item,必须包含image_urls和images两个字段。根据实际情况,可以增加其它字段
- image_urls,list类型,用来存储需下载的url列表。
- images,list类型,用于保存下载的image对象,该字段无需赋值,由scrapy自动完成。
import scrapy
class ImageItem(scrapy.Item):
image_urls = scrapy.Field()
images = scrapy.Field()
title = scrapy.Field()
settings.py
- 启动pipline
# configure item pipelines
# See https:..doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
#imageDownloadProject为工程名
#'imageDownloadProject.pipelines.MyImagePipeline':300, #使用自定义继承类重命名、改路径时使用,调整优先级为最高
#'scrapy.pipelines.images.ImagesPipeline':1 #自动保存时使用,引入ImagesPipeline,优先级设为最高
}
- 增加存储路径,IMAGES_STORE(变量名不能错)
IMAGES_STORE = './xxxxxxxxxxxxx' #新增变量,并赋值表示路径的字符串,只能指定一个路径,可使用相对路径
pipeline.py
pipeline可以不编写,通过scrapy.pipelines.images.ImagesPipeline对象自动保存图片。
若需进行重命名、分文件夹存储等操作,则需编写继承类,并重载file_path等类方法,注意先调用父类方法,获得原路径。
下面为重新分配路径时的示例:
from scrapy.pipelines.images import ImagesPipeline
from imageDownloadProject import settings #获取存取路径
import os #用于路径拼接、判断是否存在等
import re
def MyImagePipeline(ImagePipeline):
#file_path参数中没有item对象,需重写get_media_requests获取item(ImageItem)中的信息
def get_media_requests(self,item,inof):
#该方法调用在图片下载之前。它从item(示例中为ImageItem的值)中提取图片url并向服务器发送下载请求。
image_requests = super(MyImagePipeline,self).get_media_requests(item,inof)
for image_request in image_requests:
image_request.item = item #将item传至每一个下载请求,使file_path可以通过request获得item值
return image_requests #必须再次返回下载请求列表image_requests,否则不下载图片
def file_path(self,request,response=None, info=None):
#调用原方法,获得原路径(full/xxx.jpg)
originPath = super(MyImagePipeline,self).file_path(request,response,inof)
title = request.item['title']
title = re.sub(r'[\\/:<>\|\?\*]','',title) #注意:文件夹名不能有\/:<>|?*等
savePath = os.path.join(settings.IMAGES_STORE,title)
if os.path.exists(savePath ):
os.mkdir(savePath )
imageName = originPath .replace('full/'.'') #去掉默认文件夹,获取文件名
return os.path.join(savePath ,imageName)