scrapy除了官方内置的下载通道外,还可以自定义下载通道来使用。
其核心原理就是通过图像的自定义管道对官方管道scrapy.pipelines.images.ImagesPipeline进行覆盖。
常常使用的三个内置的函数:file_path()、get_media_requests()、item_completed()
(1)file_path(self,request,response = None,info = None )
每个下载的项目调用一次此方法。它返回源自指定的文件的下载路径 response。此外此方法还接收原始 request和 info。您可以重写此方法以自定义每个文件的下载路径。
图片会以hashlib.sha1加密的方式命名保存
(2)get_media_requests(item,info )
必须为每个图像URL返回一个请求。
(3)item_completed(results,item,info )
ImagesPipeline.item_completed()当对单个项目的所有图像请求均已完成(下载完成或由于某些原因失败)时,将调用该方法。
默认情况下,该item_completed()方法返回该项目。
以下是官方实例:
在爬虫文件中添加:
import scrapy
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
class MyImagesPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
yield scrapy.Request(image_url)
#一般自定义会用 get_media_requests方法中把数据传进来.
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['image_paths'] = image_paths
return item
在setting.py文件中添加:
ITEM_PIPELINES = {
'myproject.pipelines.MyImagesPipeline': 300
}
IMAGES_STORE = '/path/to/valid/dir'#文件存储位置
借鉴网站:https://blog.csdn.net/cnmnui/article/details/99850055
自己实验成功的python实例项目
1.https://www.52pojie.cn/thread-1086937-1-1.html
学习到的内容,自定义管道,如果不想用images_url这种默认的字段下载,要在setting文件中使用IMAGES_URLS_FIELD = "字段名"。
(1)get_media_requests函数可以添加自定义的Request的请求,意味着可以添加请求头。
(2)使用item_completed函数来定义下载路径来定义文件名称。
(3)import
os以及os字段来具体定义
下载路径。
(4)使用shutil这个系统自定义字段来实现文件的复制和移动。
#shutil来实现文件的复制和移动
#复制文件:
shutil.copyfile("oldfile","newfile") #oldfile和newfile都只能是文件
shutil.copy("oldfile","newfile") #oldfile只能是文件夹,newfile可以是文件,也可以是目标目录
#复制文件夹:
shutil.copytree("olddir","newdir") #olddir和newdir都只能是目录,且newdir必须不存在
#重命名文件(目录)
os.rename("oldname","newname") #文件或目录都是使用这条命令
#移动文件(目录)
shutil.move("oldpos","newpos")
shutil.move("D:/知乎日报/latest/一张优惠券,换你的通讯录信息,你愿意吗?.pdf", "D:/知乎日报/past/")
(5)os.path.exists()就是判断括号里的文件是否存在的意思,括号内的可以是文件路径。
os.rename() 方法用于重命名文件或目录
2.http://goldzl.cn/thread-4606-1-1.html,重新写一下
主要是爬虫文件文友失效,因为网页内容过期了。
import scrapy
from imagedemo3.items import Imagedemo3Item
class PhotoSpider(scrapy.Spider):
name = 'photo'
allowed_domains = ['meishij.com']
start_urls = ['https://www.meishij.net/chufang/diy/langcaipu/']
def parse(self, response):
item = Imagedemo3Item()
image_urls = response.xpath('//div[@class="listtyle1"]/a/img/@src').extract()
image_name = response.xpath('//div[@class="listtyle1"]/a/img/@alt').extract()
for i in range(0, len(image_name)):
item['image_urls'] = image_urls[i]
item['image_name'] = image_name[i]
yield item
学习的内容(1)怎么自定义下载图片的内容,使用pipeline管道file_path字段,来定义,在这其中可以筛选一些乱码。
首先定义存储图片名字的字段,用request提交上去。
def get_media_requests(self, item, info):
#这里要把image_urls字段提交上去,用meta来提交
image_url = item['image_urls']
yield scrapy.Request(image_url,meta={'name':item['image_name']})
def file_path(self, request, response=None, info=None):
name = request.meta['name'] # 接收上面meta传递过来的图片名称
name = re.sub(r'[?\\*|“<>:/]', '', name) # 过滤windows字符串,不经过这么一个步骤,你会发现有乱码或无法下载
filename= name +'.jpg' #添加图片后缀名
return filename
3.