基于Scrapy框架的图片管道实现图片抓取
前言
本文中介绍 如何基于 Scrapy 框架的图片管道实现图片抓取,并以抓取 360 图片为例进行展示。
正文
1、Scrapy框架抓取图片原理
利用 Scrapy 框架提供的图片管道类 ImagesPipeline 抓取页面图片,在使用时需要导入,并且重新 get_media_requests() 方法,如果对保存的文件名有要求,则需要重写 file_path() 方法,在 settings.py 文件中的 IMAGES_STORE 属性可以设置文件保存路径。
from scrapy.pipelines.images import ImagesPipeline
2、Scrapy框架抓取图片实现步骤
-
爬虫文件:将图片链接提取出来直接 yield 交给管道文件处理;
-
管道文件:导入并继承 scrapy 的 ImagesPipeline 类,重写get_media_requests() 方法 和 file_path() 方法;
from scrapy.pipelines.images import ImagesPipeline class XxxPipeline(ImagesPipeline): def get_media_requests(self,xxx): pass def file_path(self,xxx): #处理文件名 return filename
-
settings.py:在全局配置文件中,通过 IMAGES_STORE =“路径” 指定文件保存的位置。
3、Scrapy框架抓取图片案例
-
案例需求:抓取 360 图片的 beauty 图片并保存到本地 ./image/xxx.jpg
-
url地址:https://image.so.com/?src=tab_web
-
爬取页面posturl地址:https://image.so.com/zjl?sn={}&ch=beauty
-
F12抓包分析:
-
检查网络源代码,获取所需数据的json文件:
-
创建Scrapy项目:编写items.py文件
import scrapy class SoItem(scrapy.Item): # 图片链接 image_url = scrapy.Field() # 图片标题 image_title = scrapy.Field()
-
编写爬虫文件:
import scrapy import json from ..items import SoItem class SoSpider(scrapy.Spider): name = "so" allowed_domains = ["image.so.com"] # start_urls = ["http://image.so.com/"] url = 'https://image.so.com/zjl?sn={}&ch=beauty' def start_requests(self): """ 生成所有要抓取的url地址,一次性交给调度器入队列 :return: """ for sn in range(30, 151, 30): page_url = self.url.format(sn) yield scrapy.Request(url=page_url, callback=self.parse) def parse(self, response): """ 提取图片的链接 :param response: :return: """ html = json.loads(response.text) for one_image_list in html["list"]: item = SoItem() item["image_url"] = one_image_list["qhimg_url"] item["image_title"] = one_image_list["title"] # 图片链接提取完成后,直接交给管道文件处理即可 yield item
-
在管道文件中导入导入并继承 scrapy 的 ImagesPipeline 类,重写get_media_requests() 方法 和 file_path() 方法:
import scrapy from scrapy.pipelines.images import ImagesPipeline class SoPipeline(ImagesPipeline): # 重写 get_media_requests()方法,将图片的链接交给调度器入队列即可 def get_media_requests(self, item, info): yield scrapy.Request(url=item["image_url"], meta={"title": item['image_title']}) # 重写file_path()方法 处理文件路径及文件名 def file_path(self, request, response=None, info=None, *, item=None): image_title = request.meta['title'] filename = image_title + '.jpg' # 拼接图片名称 return filename
-
在全局配置文件中,通过 IMAGES_STORE =“路径” 指定文件保存的位置
# 指定图片保存路径 # 会存放到images下的full文件夹 IMAGES_STORE = './images/'
-
创建run.py文件运行爬虫:
from scrapy import cmdline cmdline.execute("scrapy crawl so".split())