如何使用 Scrapy 爬取网页中的图片和文件?
使用 Scrapy 爬取网页中的图片和文件需要通过 Pipeline 中的图片和文件下载器实现。
首先,在 Scrapy 项目中的 settings.py 文件中添加以下代码来启用图片和文件下载器:
ITEM_PIPELINES = { 'scrapy.pipelines.images.ImagesPipeline': 1, 'scrapy.pipelines.files.FilesPipeline': 2 } IMAGES_STORE = 'images' FILES_STORE = 'files'
上述代码中,ITEM_PIPELINES 是下载器的管道,在其中添加了图片下载器和文件下载器。由于图片下载器需要先进行图片处理,故将其放在第一位。IMAGES_STORE 和 FILES_STORE 是图片和文件本地存储的目录。
接下来,在 Spider 中返回一个包含了图片和文件链接的 Item,然后在 Item 中添加 Field 存储链接:
import scrapy class MyItem(scrapy.Item): image_urls = scrapy.Field() file_urls = scrapy.Field()
在 Spider 中通过 parse 方法获取到图片和文件链接并存入 Item:
import scrapy from myproject.items import MyItem class MySpider(scrapy.Spider): name = 'myspider' start_urls = ['http://pidancode.com'] def parse(self, response): item = MyItem() item['image_urls'] = response.css('img::attr(src)').extract() item['file_urls'] = response.css('a[href$=".pdf"]::attr(href)').extract() yield item
上述代码中,image_urls 存储的是网页中所有 img 标签的 src 属性,file_urls 存储的是所有链接以 .pdf 结尾的 a 标签的 href 属性。
最后,在 Pipeline 中实现图片和文件的下载:
import scrapy from scrapy.pipelines.images import ImagesPipeline from scrapy.pipelines.files import FilesPipeline from urllib.parse import urlparse import os class MyProjectPipeline(ImagesPipeline, FilesPipeline): def file_path(self, request, response=None, info=None): return urlparse(request.url).path.split('/')[-1] def get_media_requests(self, item, info): for url in item.get('image_urls', []): yield scrapy.Request(url, meta={'type': 'image'}) for url in item.get('file_urls', []): yield scrapy.Request(url, meta={'type': 'file'}) def item_completed(self, results, item, info): for success, data in results: if success and data['type'] == 'image': image_path = data['path'] if 'images' in image_path: item['image'] = image_path elif success and data['type'] == 'file': file_path = data['path'] if 'files' in file_path: item['file'] = file_path return item
上述代码中,继承了 ImagesPipeline 和 FilesPipeline,并分别定义了 file_path 和 get_media_requests 两个方法。其中 file_path 用于定义图片的本地存储路径,这里以文件名作为路径。get_media_requests 方法用于发起下载请求,并在 meta 中添加 type 属性,用于后续区分图片和文件。item_completed 用于将下载成功的图片和文件的本地存储路径存储在 Item 中,以便后续使用。
最后,在 Spider 中指定 Pipeline:
ITEM_PIPELINES = { 'myproject.pipelines.MyProjectPipeline': 1 }
运行 Scrapy 程序,图片和文件会分别下载到 IMAGES_STORE 和 FILES_STORE 指定的文件夹中,并在 Item 中存储对应的本地存储路径。
相关文章