案例爬取的目标是摄图网图片,根据图片的分类爬取图片并保存(原图和缩略图)
第一步:使用Item封装数据
注意属性名是固定的,如果需要改属性名,要在settings.py中设置(怎么设置这里就不写了)
第二步:编写解析函数
一共有两个解析函数,一个是获取并请求到每个主题对应的详情页的函数,一个是在详情页里获取每张图片的路径
1.获取并请求到每个主题对应的详情页
2.获取所有图片的路径,并交给ImagesPipeline执行下载,最后执行翻页操作
第三步:在pipeline下,重新设置图片下载路径及图片名称,设置缩略图
这步是可选的
第四步:配置settings.py文件
1.不遵守robots协议和USER_AGENT,这个是基本操作
2.设置图片下载路径
3.设置缩略图大小和过滤尺寸国小的图片
4.启用上面第三步编写的图片管道
解析函数:image_spider.py完整代码
from scrapy import Request
from scrapy.spiders import Spider
from shetu_image_download.items import ShetuImageDownloadItem
class ImageDownloadSpider(Spider):
name = 'image'
def start_requests(self):
url = "http://699pic.com/photo/"
#生成请求对象
yield Request(url)
#解析函数-解析照片列表页,获取各个主题对应详情页的URL
def parse(self, response):
#使用Xpath定位到每个主题对应的URL
urls = response.xpath("//div[@class='pl-list']/a[1]/@href").extract()
for i in range(len(urls)):
#这里获取回来的url没有前面http:这部分,所以要自己拼接上去,不然会无法请求
yield Request("http:" + urls[i], callback=self.parse_image)
def parse_image(self,response):
item = ShetuImageDownloadItem()
#获取所有照片的URL地址
urls = response.xpath("//li[@class='list']/a/img/@data-original").extract()
for i in range(len(urls)):
urls[i] = "http:" + urls[i]
if urls:
#获取主题名,保存时归类到不同的主题文件夹下
title = response.xpath("//li[@class='list']/a/img/@title").extract_first()
item["title"] = title
#urls是一个列表,把列表保存到image_urls,ImagesPipeline就会请求图象下载
item["image_urls"] = urls
yield item
#获取下一页
next_url = response.xpath("//a[@class='downPage']/@href").extract()
if next_url:
next_url = response.urljoin(next_url[0])
yield Request(next_url,callback=self.parse_image)
Pipeline完整代码
from scrapy.pipelines.images import ImagesPipeline
from scrapy import Request
class SaveImagePipeline(ImagesPipeline):
#构造图象下载的请求,URL从item["image_urls"]中获取
def get_media_requests(self, item, info):
#将照片主题作为参数传递出去(用于设置存储图片存储路径)
return [Request(x, meta={"title":item["title"]}) for x in item.get(self.images_urls_field, [])]
#设置图片存储路径及名称
def file_path(self, request, response=None, info=None):
#从Request的meta中获取图片类型
title = request.meta["title"]
#从路径截取图片名称,因为图片名称为路径最后一个"/"后面的字符串
image_name = request.url.split("/")[-1]
#图片存储形式:图片类型/图片名称.jpg
return "%s/%s"%(title,image_name)
#设置缩略图存储路径及名称
def thumb_path(self, request, thumb_id, response=None, info=None):
#从Request的meta中获取图片类型
title = request.meta["title"]
image_name = request.url.split("/")[-1]
#缩略图路径:图片类型名/big(或small)/图片名称
return "%s/%s/%s" % (title, thumb_id, image_name)