目录
下载文件和图片
一、为什么要选择使用 scrapy 内置的下载文件的方法:
二、下载文件的 Files Pipelines
三、下载图片的 Images Pipeline:
四、汽车之家 CRV 图片下载实战
setting.py
items.py
pipelines.py
crv_spider.py
Scrapy 为下载 item 中包含的文件(比如在爬取到产品时,同时也想保存对应的图片)提供了一个可重用的 item pipelines。这写 pipeline 有些共同的地方和结构(我们称之为 media pipeline)。一般来说你会使用 Files Pipelines 或是 Images Pipelines。
1、避免重新下载最近已经下载过的文件。
2、可以方便的指定文件存储的路径。
3、可以将下载的图片转换成通用的格式。比如 png, jpg
4、可以方便的生成缩略图
5、可以方便的检测图片的宽和高,确保他们满足最小的限制。
6、异步下载,效率非常高。
当使用 Files Pipeliens 下载文件的时候,按照以下步骤来完成:
1、定义好一个 Item, 然后在这个 item 中定义两个属性,分别为 file_urls 以及 files, file_urls 是用来存储需要下载的图片的 url 链接,需要给一个列表。
2、当文件下载完成后,会把文件下载的相关信息存储到 item 的 files 属性中。比如下载路径, 下载的url和文件的校验码等。
3、在配置文件 setting.py 中配置 FILES_STORE ,这个配置是用来设置文件下载下来的路径。
4、启动 pipeline: 在文件 setting.py 中的 ITEM_PIPELINES 设置 scrapy.pipeline.files.FilesPipeline:1 。
当使用 Images Pipeline 下载文件的时候,按照以下步骤来完成:
1、定义好一个 Item, 然后在这个 item 中定义两个属性,分别为 image_urls 以及 images 。image_urls 是用来存储需要下载的图片的url链接,需要给一个列表。
2、当文件下载完成后,会把文件下载的相关信息存储到 item 的 images 属性中。比如下载路径、下载的 url 和图片的校验等。
3、在配置文件 setting.py 中配置 IMAGES_STORE, 这个配置是用来设置图片下载下来的路径。
4、启动 pipeline : 在文件 setting.py 中的 ITEM_PIPELINES 设置 scrapy.pipeline.images.ImagesPipeline:1 。
通过 重写 ImagesPipeline 下载 CRV 这个款车的各类图片,代码如下:
import os
BOT_NAME = 'crv'
SPIDER_MODULES = ['crv.spiders']
NEWSPIDER_MODULE = 'crv.spiders'
ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY = 1
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',
}
ITEM_PIPELINES = {
'crv.pipelines.CrvImagesPipeline': 1,
}
IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "images")
import scrapy
class CrvItem(scrapy.Item):
title = scrapy.Field()
image_urls = scrapy.Field()
images = scrapy.Field()
import os
from crv import settings
from urllib import request
from scrapy.pipelines.images import ImagesPipeline
class CrvImagesPipeline(ImagesPipeline):
def file_path(self, request, response=None, info=None, *, item=None):
# 这个方法是在图片将要被存储的时候调用,来获取这个图片的存储路径。
category = item["title"]
category_path = os.path.join(settings.IMAGES_STORE, category)
image_name = request.url.split("_")[-1]
image_path = os.path.join(category_path, image_name)
print("image_path ; {}".format(image_path))
return image_path
import scrapy
from crv.items import CrvItem
class CrvSpiderSpider(scrapy.Spider):
name = 'crv_spider'
allowed_domains = ['car.autohome.com.cn']
start_urls = ['https://car.autohome.com.cn/pic/series-s46246/314.html#pvareaid=3454542']
def parse(self, response):
divs = response.xpath("//div[@class='column grid-16']/div")[2:] # 过滤掉1,2 行
for div in divs:
print(div.xpath(".//div[@class='uibox-title']"))
title = div.xpath(".//div[@class='uibox-title']/a/text()").get()
urls = div.xpath(".//ul/li/a/img/@src").getall()
urls = list(map(response.urljoin, urls))
item = CrvItem(title=title, image_urls=urls)
print(item)
yield item
目录