尝试实现一个demo项目:
步骤1.将爬取的图片以二进制存入mongodb
步骤2.从mongodb读取图片二进制流,在django前端Templates直接将二进制流显示为图片
其中遇到好多坑,调试了好久才搞定,这里做一下记录
步骤1:
爬取图片并存入mongodb,这里爬取图片可以利用我上篇博客的requests+beautifulsoup的方式先存入本地,然后(方法一)利用pymongo和gridfs库将图片以二进制形式存入mongodb,这里贴出示例代码,网上也能搜到很多相关代码
方法一:pymongo+gridfs
import pymongo
import gridfs
import os
client = pymongo.MongoClient()
db = client['images']
dir = 'F:\spider_imgs\images'
filelist = os.listdir(dir)
for file in filelist:
#print(file)
filename = dir + '\\' + file
f = file.split('.')
datatemp = open(filename,'rb')
imgput = gridfs.GridFS(db)
insertimg = imgput.put(datatemp,content_type=f[1],filename=f[0])
datatemp.close()
还可以利用(方法二)Django的mongoengine库,将本地图片存入mongodb,我理解mongoengine用来存图片的二进制流其实就是封装了pymongo+gridfs,示例代码如下
方法二:mongoengine
Django的model.py
import mongoengine
# Create your models here.
class ImageModel(mongoengine.Document):
filename = mongoengine.StringField()
data = mongoengine.FileField()
uploadDate = mongoengine.DateField()
Django的views.py里增加一个保存图片的函数,这里我先只保存了1张图1
def saveImage():
imgtmp = open(settings.STATICFILES_DIRS[0] + '/images/1.jpg','rb')
temp = models.ImageModel()
temp.filename = '1'
temp.data.put(imgtmp, content_type='image/jpeg')
temp.save()
用上述两种方式之一执行完成后,可以用robo mongodb软件查看是否保存成功
首先启动mongodb:C:\Program Files\MongoDB\Server\4.0\bin>mongod.exe --dbpath="F:\Mongodb\db"
然后启动robomongodb软件连接mongodb,可以看到db images中的collection有2条插入的数据
步骤2:
现在尝试将mongodb中的图片二进制流读取出来,并在Django的Templates中显示出来,这一步遇到了很多坑
在views中增加读取函数和Templates文件,因为是直接显示二进制,所以先用base64编码,然后html中再用base64读取
views中增加的读取函数:
def listAllImgFromDB(request):
image = models.ImageModel.objects(filename='1').first()
temp_data = image.data.read()
temp_data = base64.b64encode(temp_data)
return render(request, 'listallimg.html', {'imagedata': temp_data})
listallimg.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Images</title>
</head>
<body>
<h1>我最喜欢的球星</h1>
<br/>
<img src="">
</body>
</html>
接下来运行Django Server,然后访问网页:
我去!怎么图片显示不出来!不是已经base64编码了吗,html也设置了base64显示,怎么回事?在网上查了半天没查到解决方案,于是我打开网页的源代码看了看
我发现把圆圈中的b''去掉就可以显示图片了,
于是我搜了下怎么去掉标记为二进制的b'',在views.py中的函数增加了一行
def listAllImgFromDB(request):
image = models.ImageModel.objects(filename='1').first()
temp_data = image.data.read()
temp_data = base64.b64encode(temp_data)
temp_data = bytes.decode(temp_data)
return render(request, 'listallimg.html', {'imagedata': temp_data})
再次访问页面,显示成功!
总结
这个小项目只是自己想尝试下存图片二进制到mongodb,并在页面上直接显示二进制图,用base64编码,在用decode解码去掉影响前端显示的b‘’确实让自己花了不少时间,不过总算是实现了,后面还需继续加油学习提升自己!