大致流程
下载图片需要用到ImagesPipeline
这个类,首先介绍下工作流程:
- 1 首先需要在一个爬虫中,获取到图片的url并存储起来。
- 2 项目从爬虫返回,进入到项目通道也就是
pipelines
中 - 3 在通道中,在第一步中获取到的图片
url
将被scrapy
的调度器和下载器安排下载。 - 4 下载完成后,将返回一组列表,包括下载路径,源抓取地址和图片的校验码
大致的过程就以上4步
未完成scrapy的安装请转:https://www.jianshu.com/p/2099badf4238
抓取目标
文轩网中书的图片http://www.winxuan.com/
最终效果:
开始制作
1.新建scrapy
项目
在你喜欢的地方(喜欢的地方是D:\py_projects
)运行cmd
然后运行命令
scrapy startproject wgdemo
其中wgdemo
为项目名字
在pycharm中打开项目,然后在spiders
的文件夹中新建.py文件
最终项目结构:
2.需要写的文件
这里需要定义一个item(它好像自动会生成一个,我们就将就这个)
他有点“像java中定义一个类吧”
import scrapy
class WgdemoItem(scrapy.Item):
imgurl = scrapy.Field()#用来存储图片的链接
imgname = scrapy.Field()#用来存储图片的名字
pass#就是用来过渡没啥作用
编写蜘蛛文件
import scrapy
from wgdemo.items import WgdemoItem #引入刚才定义的WgdemoItem
class imgSpider(scrapy.Spider):#定义一个蜘蛛,必须继承scrapy.Spider
name = 'imgSpider' #蜘蛛的名字,运行的时候后面加的就是这个名字
start_urls = ['http://www.winxuan.com/']#目标网址,多个用逗号隔开
def parse(self, response):#处理函数 名字不能变
myitem = WgdemoItem()# 实例化item相当于定义一个类
# 注意这里是一个集合也就是多张图片
imgurls = response.css(".cell-m-book-top-p img::attr(data-original)").extract()
myitem['imgurl'] = imgurls
# 注意这里是一个集合也就是所有名字的数组
imgnames = response.css(".cell-m-book-top-p img::attr(alt)").extract()
myitem['imgname'] = imgnames
yield myitem#我理解为返回这个item 必须要有
其中response.css(".cell-m-book-top-p img::attr(data-original)").extract()
应该不用说吧
搜索scrapy css选择器 一大推教程
图片下载中间件pipeline编写:
这里的话主要继承了scrapy的:ImagesPipeline这个类,我们需要在里面实现:
def get_media_requests(self, item, info)这个方法,
这个方法主要是把蜘蛛yield过来的图片链接执行下载,灰常的简单
def file_path(self, request, response=None, info=None) 这个方法
便是图片重命名以及目录归类的方法,我们只需要重写里面的一些内容,
便可轻松实现scrapy图片重命名,图片保存不同目录。
from scrapy.pipelines.images import ImagesPipeline
from scrapy import Request
import re
class WgdemoPipeline(ImagesPipeline):
def get_media_requests(self, item, info):#这个方法主要是把蜘蛛yield过来的图片链接执行下载
for i,image_url in enumerate(item['imgurl']):
# meta里面的数据是从spider获取,然后通过meta传递给下面方法:file_path
if image_url.startswith('http:'):#因为得到的链接有区别 看下图
pass
else:
image_url = "http:" + image_url
yield Request(image_url, meta={'name': item['imgname'][i]})
def file_path(self, request, response=None, info=None):
# 接收上面meta传递过来的图片名称
name = request.meta['name']+'.jpg'
# 过滤windows字符串,不经过这么一个步骤,你会发现有乱码或无法下载
name = re.sub(r'[?\\*|“<>:/]', '', name)
#以u或U开头的字符串表示unicode字符串
filename = u'{0}'.format(name)
return filename
为什么有if else来处理链接
设置,启动图片下载
# 设置图片存储目录
IMAGES_STORE = 'F:\ImageSpider'
# 启动下载器
ITEM_PIPELINES = {
'wgdemo.pipelines.WgdemoPipeline': 300,
}
启动爬虫
进入wgdemo目录,命令行输入:
scrapy crawl imgSpider