爬虫2.4-scrapy框架-图片分类下载
scrapy框架-图片下载
python小知识:
map函数:将一个可迭代对象的每个值,依次交给一个函数处理,返回一个生成器。
urls = uibox.xpath(".//ul/li/a/img/@src").getall()
urls = list(map(lambda url: 'https:'+url, urls))
urls本身是一个列表,使用map函数,将urls中的每一项传递给url ,并让url执行‘https:’+url的操作。 lambda则是一个无名函数,方便一行内写完函数。最后用list函数将map返回的生成器转成列表
1 传统下载方法:
pipelines.py
def process_item(self, item, spider):
category = item['category'] # 一个字符串
urls = item['urls'] # 一个列表
local_path = os.path.abspath('.') # 获取绝对路经
os.mkdir(r'{}\images\{}'.format(local_path, category)) #分类创建images/category文件夹
for url in urls:
filename = url.split('_')[-1] # 获取图片名
request.urlretrieve(url, '{}\images\{}\{}'.format(local_path, category, filename)) # 将图片下载到/images/category/filename
缺点是非异步,图片是一张一张按顺序下载的,数量较大时效率低
2 scrapy框架的下载方法
scrapy.pipelines中提供了两个下载文件的子类
一个是scrapy.pipelines.files 中的FilesPipeline,另一个是scrapy.pipelines.images 中的ImagesPipeline
其中ImagesPipeline专门用于下载图片,是继承自FilesPipeline
ImagesPipeline使用方法
1)在items.py中定义好image_urls和images,image_urls是用来存储需要下载的图片的url,需要给一个列表,images中需要保存图片的属性,如下载路径、url、图片的校验码等
2)当图片下载完成后,会把文件下载的相关信息存储到item中的images属性中。
3)在配置文件settings.py中配置IMAGES_STROE,这个配置是用来设置图片下载路径的
4)启动pipeline,在ITEM_PIPELINES中注释原来的pepeline设置'scrapy.pipelines.images.ImagesPipeline':1
FilesPipeline使用方法类似
定义好file_urls和file,设置好FILES_STORE,以及ITEM_PIPELINES中的scrapy.pipelines.files.FilesPipeline:1
2.1 将图片全部下载到full文件夹下
本来高高兴兴来到实验室,2分钟就把需要整的步骤整完了,如何折腾了一个小时都没想通为什么爬虫无法执行parse()函数,各种百度,最后对比之前写的爬虫发现,我睡了午觉起来迷迷糊糊将start_urls 改成了start_image_urls 这样的话scrapy框架一检查,没有开始点啊,那直接就结束了。。。。
1)修改setttings.py 注释掉原来的ITEM_PIPELINES中的内容,添加'scrapy.pipelines.images.ImagesPipeline': 1
并添加图片存储路径IMAGES_STORE = os.path.join(os.path.abspath('.'), 'images')
~ settings.py
ITEM_PIPELINES = {
# 'bmw.pipelines.BmwPipeline': 300,
'scrapy.pipelines.images.ImagesPipeline': 1
}
IMAGES_STORE = os.path.join(os.path.abspath('.'), 'images') # 爬虫项目根目录/images
2)修改items.py 添加或修改 image_urls和images
image_urls = scrapy.Field()
images = scrapy.Field()
3)修改[spider.py] yield image_urls
item = BmwItem(category=category, image_urls=image_urls) # 重点在于image_urls
yield item
执行,得到结果:./images/full 目录下下载了一堆没有分类的图片
这个时候就想怎么讲图片分类下载好,比如车身图片(实验代码以汽车之家宝马5x图片进行下载)就在/images/车身,内部图片在/images/内部,这样强迫症才舒服
2.2 将图片分类到不同目录
这里就需要重写scrapy.pipelines.images.ImagesPipeline里面的一些方法了。
这里需要注意:parse()函数中yield 抛出的数据格式为 category: ‘xxx’ image_urls: ['url', 'url'....] images: ''
所以在之后操作时,每次抛出的image_urls 都对应着同一个category
1)继承ImagesPipeline,并改写一些返回值
from bmw import settings # bmw是项目名
import os # 2)中需要用到
class BMWImagesPipeline(ImagesPipeline): # 新定义一个子类,继承ImagesPipeline
def get_media_requests(self, item, info):
request_objs = super(BMWImagesPipeline, self).get_media_requests(item, info)
for request_obj in request_objs:
request_obj.item = item # 为每个request_obj对象添加item属性,里面包含了category
return request_objs # 父类中必须返回这个列表,给其他函数使用
get_media_requests函数原本返回的是[Request(x) for x in item.get(self.images_urls_field, [])],即返回了一个Request(url)的列表,这里改造一下,使用super重复父类中的方法,得到一个返回值,并添加了item属性,方便下一步使用。
2)重写file_path()方法
def file_path(self, request, response=None, info=None):
# path获取父类中file_path方法返回的值即‘full/hash.jpg' hash是图片的哈希值
path = super(BMWImagesPipeline, self).file_path(request, response, info)
#request即前一个函数返回的列表中的每一项,所以有item属性
category = request.item.get('category')
images_store = settings.IMAGES_STORE # IMAGES_STORE是需要下载到的路径,例如c:/images
category_path = os.path.join(images_store, category) # 创建每个种类的路径并判断是否已存在
if not os.path.exists(category_path):
os.mkdir(category_path)
image_name = path.replace('full/', '') # 去掉原本的'full/' 只留下文件名
image_path = os.path.join(category_path, image_name)
# 图片完整的路径和文件名c:/images/aaa/js451v88225F45sd42f4y4.jpg
return image_path
3)修改settings.py中的配置
ITEM_PIPELINES = {
# 'bmw.pipelines.BmwPipeline': 300, 注释掉原有的pipeline
'bmw.pipelines.BMWImagesPipeline': 1
}
IMAGES_STORE = os.path.join(os.path.abspath('.'), 'images') # 添加图片保存地址
完工,重写之后每个图片的路径就包含了自己的种类,下载完成后目录格式如下:
images
车头
41312r322r2234.jpg
1425flj5l2.jpg
车身
。。
3 分类下载完整代码
项目名:bmw 爬虫名:bmw5x
bmw5x.py
import scrapy
from bmw.items import BmwItem
class Bmw5xSpider(scrapy.Spider):
name = 'bmw5x'
allowed_domains = ['car.autohome.com.cn']
start_urls = ['https://car.autohome.com.cn/pic/series/65.html#pvareaid=2042209']
def parse(self, response):
uiboxs = response.xpath("//div[@class='uibox']")[1:]
for uibox in uiboxs:
category = uibox.xpath("./div/a/text()").get()
image_urls = uibox.xpath(".//ul/li/a/img/@src").getall()
image_urls = list(map(lambda url: 'https:'+url, image_urls))
item = BmwItem(category=category, image_urls=image_urls)
yield item
items.py
import scrapy
class BmwItem(scrapy.Item):
category = scrapy.Field()
image_urls = scrapy.Field()
images = scrapy.Field()
pipelines.py
import os
from scrapy.pipelines.images import ImagesPipeline
from bmw import settings
class BMWImagesPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
request_objs = super(BMWImagesPipeline, self).get_media_requests(item, info)
for request_obj in request_objs:
request_obj.item = item
return request_objs
def file_path(self, request, response=None, info=None):
path = super(BMWImagesPipeline, self).file_path(request, response, info)
category = request.item.get('category')
images_store = settings.IMAGES_STORE
category_path = os.path.join(images_store, category)
if not os.path.exists(category_path):
os.mkdir(category_path)
image_name = path.replace('full/', '')
image_path = os.path.join(category_path, image_name)
return image_path
settings.py
import os
ROBOTSTXT_OBEY = False
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent': 'xxx',
'Referer': 'xxx',
'Cookie': 'xxx'
}
ITEM_PIPELINES = {
'bmw.pipelines.BMWImagesPipeline': 1
}
IMAGES_STORE = os.path.join(os.path.abspath('.'), 'images')
爬虫2.4-scrapy框架-图片分类下载的更多相关文章
- 第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码
第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码 打码接口文件 # -*- coding: cp936 -*- import sys import os ...
- 第三百三十一节,web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令
第三百三十一节,web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令 Scrapy框架安装 1.首先,终端执行命令升级pip: python -m pip install --u ...
- Python爬虫进阶之Scrapy框架安装配置
Python爬虫进阶之Scrapy框架安装配置 初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此 ...
- 第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息
第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息 crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多 ...
- 第三百三十三节,web爬虫讲解2—Scrapy框架爬虫—Scrapy模拟浏览器登录—获取Scrapy框架Cookies
第三百三十三节,web爬虫讲解2—Scrapy框架爬虫—Scrapy模拟浏览器登录 模拟浏览器登录 start_requests()方法,可以返回一个请求给爬虫的起始网站,这个返回的请求相当于star ...
- 第三百三十二节,web爬虫讲解2—Scrapy框架爬虫—Scrapy使用
第三百三十二节,web爬虫讲解2—Scrapy框架爬虫—Scrapy使用 xpath表达式 //x 表示向下查找n层指定标签,如://div 表示查找所有div标签 /x 表示向下查找一层指定的标签 ...
- python爬虫入门(六) Scrapy框架之原理介绍
Scrapy框架 Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬 ...
- 爬虫入门之Scrapy 框架基础功能(九)
Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非 ...
- 芝麻HTTP:Python爬虫进阶之Scrapy框架安装配置
初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此整理如下. Windows 平台: 我的系统是 ...
随机推荐
- C#泛型约束 (转载)
六种类型的约束: T:结构 类型参数必须是值类型.可以指定除 Nullable 以外的任何值类型.有关更多信息,请参见使用可空类型(C# 编程指南). T:类 类型参数必须是引用类型,包括任何类.接口 ...
- MySQL----MySQL数据库入门----第四章 单表查询
select [distinct] * | 字段1,字段2,字段3... from 表名 [where 条件表达式] [group by 字段名] [having 条件表示式] [order by 字 ...
- PHP操作redis之String(字符串)、List(列表)(一)
Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key – value 缓存产品有以下三个特点: Redis支持数据的持久 ...
- 大数据学习:Spark是什么,如何用Spark进行数据分析
给大家分享一下Spark是什么?如何用Spark进行数据分析,对大数据感兴趣的小伙伴就随着小编一起来了解一下吧. 大数据在线学习 什么是Apache Spark? Apache Spark是一 ...
- STM32 HAL库学习系列第4篇 定时器TIM----- 开始定时器与PWM输出配置
基本流程: 1.配置定时器 2.开启定时器 3.动态改变pwm输出,改变值 HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); 函数总结: __HAL_TIM ...
- 树莓派安装SimpleCV
开源计算机视觉框架.python2 安装 (http://simplecv.readthedocs.io/en/latest/HOWTO-Install%20on%20RaspberryPi.html ...
- python 运算符与分支结构
运算符与分支结构 运算符 赋值运算符 用'='表示,左边只能是变量 算术运算符 +.-.*:加.减.乘 /:除法运算,结果是浮点型 //:除法运算,结果是整型 %:求余 **:求幂 复合运算符 +=. ...
- 核密度估计 Kernel Density Estimation (KDE) MATLAB
对于已经得到的样本集,核密度估计是一种可以求得样本的分布的概率密度函数的方法: 通过选取核函数和合适的带宽,可以得到样本的distribution probability,在这里核函数选取标准正态分布 ...
- 20155213 2016-2017-2《Java程序设计》课程总结
20155213 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:我所期望的师生关系 预备作业2:C语言的学习的回忆 预备作业3:小议linux 第一周作 ...
- 20155218 《Java程序设计》实验五(网络编程与安全)实验报告
20155218 <Java程序设计>实验五(网络编程与安全)实验报告 一.实验内容及步骤 (一) 编写MyBC.java实现中缀表达式转后缀表达式的功能 编写MyDC.java实现从上面 ...