[python] 溜了,溜了,七牛云图片资源批量下载 && 自建图床服务器


故事背景:

七牛云最近一波测试域名操做真是把我坑死了!这简直和百度赠送你2T网盘,以后再限速同样骚操做。因而,痛定思痛本身买个云主机、本身搭图床应用!html


一、七牛图片批量下载到本地

1.1 曲折尝试前端

当测试连接不能用的时候,我想依次用到下面几个方法尝试download图片:python

  • 用七牛以前的传图工具qshell,看看有啥办法(行不通)
  • 找七牛图片资源处看看有没有批量打包下载(NO)
  • 本身写个前端爬虫将图片爬下来(没下载连接...)
  • 绑定一个本身的域名(须要实名认证+域名备案)
    ...

最后发现一个神器:qfetch,是根据七牛云存储API实现的一个简易命令行辅助工具。覆盖七牛云存储开发者网站包含的大部分甚至更高级的功能。开发者在对七牛云存储 API 有基本了解的状况下,此工具将会很是适用。nginx

 
1.2 qfetch基本操做web

-按照以下指令,输入本身七牛云的帐号和密码登陆shell

./qrstcl login <your username> <your password>

因为我以前全部图片是在七牛云对象存储中的bucket中,运行以下代码查看目前我创建的全部bucket:apache

./qrsctl buckets

我里面只有一个buckets:beautifulzzzzjson

能够用下列命令查看该buckets下的全部资源:(注意最后是两个英文单引号)bootstrap

./qrsctl listprefix beautifulzzzz ''

获得资源列表后,能够调用下列命令下载一个资源:vim

qrsctl get <Bucket> <Key> <DestFile>
好比./qrsctl get beautifulzzzz 1.jpg ./1.jpg能够将picture中的1.jpg下载到本地机器当前路径下的1.jpg

 
1.3 自动化脚本

综上几步,能够写一个自动化脚本:

qiniuyun (master) ✗ cat download.sh 
#!/bin/bash
imgs=`./qrsctl listprefix beautifulzzzz ''`

i=0 
echo $imgs | tr " " "\n" | while read line
do
    if(($i>0))
    then
    echo $line
    path=`dirname $line`
    echo $path
    if [ ! -d "$path" ];then
        mkdir -p $path
    fi

    ./qrsctl get beautifulzzzz $line ./$line
    fi
    i=$(($i+1))
done

注:该脚本相对于 chensonglu 分享的《七牛云测试域名失效致使图片外链失效的解决办法》,增长了多级目录文件下载功能。


二、python 图床服务器搭建

2.1 python3环境搭建

安装python:

sudo apt-get install python2.7-dev python3-dev
wget https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py

安装python虚拟环境virtualenv virtualenvwrapper:(用虚拟开发环境能够为每一个工程提供独立的python开发环境、独立的包、独立的版本,每一个独立的环境会在~/.virtualenvs/下造成资源包~)

sudo pip install virtualenv virtualenvwrapper
sudo rm -rf ~/.cache/pip

以后在~/.profile文件最后添加下面几行:

# virtualenv and virtualenvwrapper
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

以后若是想用python虚拟环境,在每次打开一个新的terminal就要执行一次source ~/.profile

$ source ~/.profile

接下来咱们生成一个python虚拟环境来用于python_pic_server的开发提供环境:(这里不讲python2,强烈建议用python3)

mkvirtualenv python_pic_server -p python3

注:再次说明python虚拟环境是彻底独立的,也就是说在python_pic_server的环境下安装的python包,步适用于全局;在全局安装的包,不适合python_pic_server。

如何验证你如何将python_pic_server环境生成好了呢?——新开一个terminal,执行下列命令:

$ source ~/.profile
$ workon python_pic_server

若是terminal前面的文字变成了(python_pic_server)代表成功建立了名为python_pic_server的python虚拟环境,在接下来的操做中都要保持在python_pic_server环境中!

 
2.2 安装Sanic

sanic 是一个比较新的,可是发展比较快的框架。其特征是速度很是快。据他们官方网站本身说,sanic 是最快的 python 框架。

Sanic is a Flask-like Python 3.5+ web server that’s written to go fast. It’s based on the work done by the amazing folks at magicstack, and was inspired by this article.

在python_pic_server中安装sanic:

pip install sanic

sanic用法比较简单,具体能够参考:[6].sanic getting started page

 
2.3 写图床服务器程序

在/root/App/python_pic_server目录下建立run.py:

(python_pic_server) ➜  python_pic_server cat run.py 
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from sanic import Sanic
from sanic.log import logger
from sanic.response import json, text, file
import os, sys
import hashlib
import base64

app = Sanic()
# 图片存储目录
baseDir = sys.path[0] + '/image/'
# 校验 Token 写死就成,反正本身用的嘛
token = 'SheIsABeautifulGirl'
# 容许的域名列表
allowHost = [
        '127.0.0.1:8000',
        'localhost',
        'pic.phage.com'
    ]

# 成功返回方法
def ok(data):
    if type(data) == list:
    return json({"data": {"list": data}, "status": 0})
    else:
    return json({"data": data, "status": 0})
# 失败返回方法
def fail(data):
    return json({"data": data, "status": 1})

# 获取图片后缀名
def getSuffix(filename):
    tempArr = filename.split('.')
    suffix = tempArr[-1]
    fileType = ['jpg', 'jpeg', 'gif', 'png']
    if len(tempArr) < 2:
    return 'error name'
    elif suffix not in fileType:
    return 'error type'
    else:
    return suffix
# 检查请求地址是否受权
def checkHost(host):
    for i in allowHost:
    if i in host:
        return True
    return False

# 上传图片文件接口
@app.route('/api/v1/upimg', methods=['POST'])
async def upimg(request):
    # 判断用户是否具备上传权限
    if request.headers.get('token') != token:
    return fail('您没有使用本服务的权限')
    image = request.files.get('file').body
    # 判断文件是否支持
    imageName = request.files.get('file').name
    imageSuffix = getSuffix(imageName)
    if 'error' in imageSuffix:
    return fail(imageSuffix)
    # 组织图片存储路径
    m1 = hashlib.md5()
    m1.update(image)
    md5Name = m1.hexdigest()

    # 用 md5 的前两位来建文件夹,防止单个文件夹下图片过多,又或者根目录下创建太多的文件夹
    saveDir = baseDir + md5Name[0:2] + '/'
    savePath = saveDir + md5Name[2:] + '.' + imageSuffix
    resPath = '/' + md5Name[0:2] + '/' + md5Name[2:] + '.' + imageSuffix

    # 若是文件夹不存在,就建立文件夹
    if not os.path.exists(saveDir):
    os.makedirs(saveDir)

    # 将文件写入到硬盘
    tempFile = open(savePath, 'wb')
    tempFile.write(image)
    tempFile.close()

    # 给客户端返回结果
    return ok({"path": resPath})

# 请求图片接口
@app.route('/', methods=['GET'])
async def img(request):
    # 判断是否为网站请求,不然就加上自定义的字符串(容许本地访问)
    host = request.headers.get('host') or 'no_host'
    # 判断请求接口是否带参数,不然加上自定义字符串(没有这个文件夹,返回404)
    args = request.args.get('path') or 'no_file'
    # 拼接文件地址
    path = baseDir + args
    #logger.info(request.headers)
    #logger.info(path)
    #logger.info(host)
    # 若是不在容许列表,则展现 401 图片
    if not checkHost(host):
    path = baseDir + '/cb/fea262f9b861c6fce14d3c3c8ba9a1.png'
    # 若是文件不存在,则展现 404 图片
    if not os.path.exists(path):
    path = baseDir + '/b4/dcd9ad1068ae6aa41ce486fa7f2739.png'
    # 返回文件
    logger.info(path)
    return await file(path)
# 启动服务
if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8000)

 
2.4 nginx配置

vim /etc/nginx/nginx.conf 编辑配置文件,在http模块的最后添加:

server {
    listen 3000;
    server_name tuchuang.beautifulzzzz.com;
    location / {
        proxy_pass  http://127.0.0.1:8000;
    }
}

修改好以后relaod一下nginx:

nginx -s reload

这样访问 tuchuang.beautifulzzzz.com:3000 就至关于访问本机的8000端口,正好是咱们的图床服务器端口!

注:别忘了在你购买域名的地方设置一下A解析!我没备案,所以就用了3000端口。

 
2.5 运行图床并使用

将第1步下载的七牛云图片放在image目录下,而后将run.py设置为可执行,并执行:

chmod +x run.py
./run.py

注:想在后台执行能够用:nohup ./run.py &

此时,访问图片能够经过 (/image/20180926/flygame.png)

http://tuchuang.beautifulzzzz.com:3000/?path=/20180926/flygame.png

上传图片能够经过:

curl http://tuchuang.beautifulzzzz.com:3000/api/v1/upimg -F "file=@a.png" -H "token: SheIsABeautifulGirl" -v


三、shell脚本批量替换某文件夹下文件中的域名字串

如今,准备写一个批处理脚本进行善后。我首先想到的是用下面命令直接搞定:

sed -i "s/A/B/g" `grep -rl A`

但是发现grep出来的文件目录中带有空格,这样这条命令就处理不到!

因而本身写了一个循环查找替换的批处理脚本:

doc (master) ✗ cat change.sh 
#!/bin/bash
#bash change.sh "odff1d90v.bkt.cloudd
#n.com" "tuchuang.beautifulzzzz.com:3000\/?path="

#bash change.sh "sed src string" "sed dst string"
IFS=$'\n'

if [ "$1" = "" ] && [ "$2" = "" ];then
    echo "params 2"
    exit
fi

for element in `grep -rl "$1"`
do
    #echo $element
    cmd="s/$1/$2/g"
    echo $cmd
    sed -i $cmd $element
done

注:这里IFS=$'\n'是为了让FOR循环的时候以换行做为分割

使用的时候只要将该文件放置在对应的ROOT目录中,执行:

bash change.sh "odff1d90v.bkt.clouddn.com" "tuchuang.beautifulzzzz.com:3000\/?path="

注:change.sh的两个参数就是sed的被替换对象和替换对象,注意转译符!


[1].七牛云测试域名失效致使图片外链失效的解决办法
[2].命令行辅助工具(qrsctl)
[3].Linux shell 之 提取文件名和目录名的一些方法
[4].逐行处理文本文件-一点心青-cnblog
[5].shell中的特殊变量IFS- __Cheny-csdn
[6].sanic getting started page
[7].Python3 初学实践案例(14)打造一个私人图床服务器-FungLeo-csdn
[8].Python 打造本身的图床升级篇 - PIL 为图片添加水印-FungLeo-csdn
[9].nohup和&后台运行,进程查看及终止-弥尘-cnblog


@beautifulzzzz
智能硬件、物联网,热爱技术,关注产品
博客:http://blog.beautifulzzzz.com
园友交流群:414948975
相关文章
相关标签/搜索