目錄
下載下傳檔案和圖檔
一、為什麼要選擇使用 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。
一、為什麼要選擇使用 scrapy 内置的下載下傳檔案的方法:
1、避免重新下載下傳最近已經下載下傳過的檔案。
2、可以友善的指定檔案存儲的路徑。
3、可以将下載下傳的圖檔轉換成通用的格式。比如 png, jpg
4、可以友善的生成縮略圖
5、可以友善的檢測圖檔的寬和高,確定他們滿足最小的限制。
6、異步下載下傳,效率非常高。
二、下載下傳檔案的 Files Pipelines
當使用 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:
當使用 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 。
四、汽車之家 CRV 圖檔下載下傳實戰
通過 重寫 ImagesPipeline 下載下傳 CRV 這個款車的各類圖檔,代碼如下:
setting.py
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")
items.py
import scrapy
class CrvItem(scrapy.Item):
title = scrapy.Field()
image_urls = scrapy.Field()
images = scrapy.Field()
pipelines.py
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
crv_spider.py
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
目錄