下面就给您详细讲解“Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码”的完整攻略。
爬取全站图片的步骤
实现这个功能可以分为以下几个步骤:
- 创建Scrapy爬虫项目
- 编写item和pipelines,用于下载图片并保存到本地
- 编写spider,用于爬取全站的图片,并将图片url交由pipelines处理下载
接下来我们将一步步展开讲解:
1. 创建Scrapy爬虫项目
使用scrapy脚手架命令创建一个Scrapy项目:
scrapy startproject image_scraper
其中,"image_scraper"是您要创建的项目名称。
2. 编写item和pipelines
Scrapy框架的item和pipelines是用于处理和存储数据的。
在项目根目录下的image_scraper文件夹中,创建一个名为items.py的文件。在items.py中定义如下类:
import scrapy
class ImageScraperItem(scrapy.Item):
image_urls = scrapy.Field()
images = scrapy.Field()
接下来,创建一个名为pipelines.py的文件。并添加以下代码:
import scrapy
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
import os
from PIL import Image
class ImageScraperPipeline(ImagesPipeline):
def file_path(self, request, response=None, info=None):
image_guid = request.url.split("/")[-1]
return 'full/%s' % (image_guid)
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
yield scrapy.Request(image_url)
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
item['images'] = image_paths
return item
def thumb_image(self, image, thumb_width, thumb_height):
thumb_image = Image.new('RGBA', (thumb_width, thumb_height), (255, 255, 255, 0))
img_width, img_height = image.size
if img_width > thumb_width or img_height > thumb_height:
ratio = min(thumb_width/img_width, thumb_height/img_height)
size = int(img_width*ratio), int(img_height*ratio)
image = image.resize(size, Image.ANTIALIAS)
thumb_image.paste(image, ((thumb_width - size[0]) // 2, (thumb_height - size[1]) // 2))
return thumb_image
def thumb_path(self, request, thumb_id, response=None, info=None):
thumb_guid = thumb_id + "_" + request.url.split("/")[-1]
return 'thumbs/%s' % (thumb_guid)
3. 编写spider
在项目根目录下的image_scraper文件夹中,创建一个名为spiders的文件夹。在spiders文件夹中创建一个名为image_scraper_spider.py的文件。并添加如下内容:
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from image_scraper.items import ImageScraperItem
class ImageScraperSpider(CrawlSpider):
name = 'image_scraper_spider'
allowed_domains = ['example.com']
start_urls = ['http://example.com/']
rules = (
Rule(LinkExtractor(), callback='parse_item', follow=True),
)
def parse_item(self, response):
item = ImageScraperItem()
item['image_urls'] = response.css('img::attr(src)').extract()
return item
在上面的代码中,我们使用了CrawlSpider类来创建了一个爬虫类。里面定义了一个start_urls的属性,它表示起始的URL。通过规则规定了提取链接和回调函数。
最后,在命令行中执行以下命令,开始全站爬取图片并保存到本地:
scrapy crawl image_scraper_spider
示例说明:
示例一
假设我们要爬取的是“http://www.example.com”这个网站,我们可以在ImageScraperSpider类中的start_urls属性中添加该网站的链接:
class ImageScraperSpider(CrawlSpider):
name = 'image_scraper_spider'
allowed_domains = ['example.com']
start_urls = ['http://example.com/']
这样设置之后,我们的Scrapy爬虫就会从该网站开始全站爬取,获取所有的图片链接。
示例二
假设我们要将爬取到的图片进行缩略,我们可以修改pipelines.py文件中的ImageScraperPipeline类增加一个thumbnail方法:
def thumbnail(self, image, size):
image.thumbnail(size)
return image
并在pipeline.py文件中item_completed函数中调用thumbnail方法:
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
item['images'] = image_paths
for img_path in item['images']:
img = Image.open(os.path.join(item['images_store'], img_path))
thumb_image = self.thumbnail(img, (100, 100))
thumb_path = self.thumb_path(None, "thumb", None, None)
thumb_image.save(os.path.join(item['images_store'], thumb_path))
return item
这样设置之后,我们就可以获取到每张图片的缩略版本了。
这就是“Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码”的详细攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码 - Python技术站