ImagePipelineとは?
ScrapyにはURLを渡すと画像ファイルをダウンロードして所定のフォルダに入れてくれる便利機能があります。ただ、以下の特徴になっているので適宜カスタマイズが必要になります。
- デフォルトでランダムなファイル名
- 保存場所が一定
注意点
画像ファイルをダウンロードするには完全な形の「絶対URL」が必要になります。(相対URLだとダウンロードできないです。)、絶対URLが画像に使ってあるサイトなら特に意識しなくても良いのですが相対パスが指定されている場合は必ず以下の加工をした上でImagePipelineでは扱ってあげる必要があります。
指定方法1
1 |
f'https://xxx.com/{相対ドメイン名}' |
指定方法2
1 |
response.urljoin(相対URL) |
scrapy/projects/プロジェクト名/プロジェクト名/items.py
まずは、Items.pyに対して画像を格納するフィールドを定義します。
1 2 3 |
import scrapy class XXXItem(scrapy.Item): image_urls = scrapy.Field() |
spiderのコード
1 2 3 4 |
def parse_item(self, response): loader = ItemLoader(item=BookItem(), response = response) loader.add_value('image_urls',response.urljoin(response.xpath('取得画像のXPath').get())) yield loader.load_item() |
response.urljoinを使って絶対URLを取得します。response.urljoin自体にXpathを渡すのではなく相対URLを渡したいのでresponse.xpathにて相対URLを取得します。
ItemLoaderはadd_valueでXpathなどを使わずそのままItemに格納します。
settings.pyの設定
1 2 3 4 5 6 |
ITEM_PIPELINES = { "scrapy.pipelines.images.ImagesPipeline": 400, } IMAGES_STORE = r'任意のパス/projects/プロジェクト名/images' IMAGES_URLS_FIELD = 'image_urls' |
ITEM_PIPELINES
ImagePipelineの優先度の設定です。通常の自作pipelineと違ってscrapy本来が持っている機能なので指定はscrapyから始まります。
IMAGES_STORE
画像の保存先になります。お使いのPC上の任意の絶対パスなどで大丈夫です。パスの前には「r」を付けます。パスの中には円マークやバックスラッシュなどが含まれているのでこれを正しく認識できるようにするためです。
IMAGES_URLS_FIELD
画像ファイルのURLを格納したItemのフィールド名を指定します。この記事では「image_urls」という名前のフィールド名にしているのでその名前を指定しています。
ImagePipelineのコードをオーバーライドする。
現状だとfullというディレクトリに帰って来ています。それを防止するために以下のようにImagePipelineのコードを上書きしてファイル名だけ取得するようにします。
pipelines.pyにて以下のように記述します。
1 2 3 4 5 |
from scrapy.pipelines.images import ImagesPipeline class customImagePipeline(ImagesPipeline): def file_path(self,request,response=None, info=None,*,item=None): return request.url.split('/')[-1] |
settings.py
ITEM_PIPELINESの方の設定もオーバーライドしたメソッドを呼び出すようにします。
1 2 3 |
ITEM_PIPELINES = { "プロジェクト名.pipelines.customImagePipeline": 400, } |
この記事へのコメントはありません。