iblogc

七牛云文件免费删除脚本

七牛云文件免费删除脚本
2023-04-04 · 4 min read
Python

在清理七牛云文件时发现,七牛云网址上删除文件夹操作竟然是在网页前面轮询一个一个删除的,但删除除了控制台网络请求里不断有请求,网页上没有任务反馈,也不知道删除多少什么时候删除完成,所以就写了一个脚本来模拟网页上的请求,这个删除请求不会计算在账户的DELETE请求数里,所以不会有单独计费,如果单次删除操作量大的,可以使用这个方式来节省费用(官网写的PUT/DELETE每月免费次数为10万)

import requests
import base64
import traceback

payload = {}
# 填入自己的 cookies
headers = {
    'authority':
        'portal.qiniu.com',
    'dnt':
        '1',
    'x-reqid':
        'abc',
    'Cookie':
        'xxx',
    'User-Agent':
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.62'
}

base_url = 'https://portal.qiniu.com'
# 要删除的文件所在的 bucket
bucket = 'hmp-public'
# 要删除的文件目录
prefix = 'sandbox3/channelSetMeal/img/'
query_url = '{}/api/kodov2/rsf/list?allversion=false&bucket={}&prefix={}&limit=50'.format(base_url, bucket, prefix)
delete_url = '{}/api/proxy/rs/delete/'.format(base_url)

has_next = True
del_file_size_byte = 0
del_file_count = 0
except_msgs = []
while has_next:
    try:
        query_res = requests.request("GET", query_url, headers=headers, data=payload)
        if query_res.status_code != 200:
            break
        items = query_res.json()['items']
        has_next = True if len(items) else False
        if not has_next:
            break
        for item in items:
            del_file_size_byte += item['fsize']
            del_file_count += 1
            sid = 'hmp-public:' + item['key']
            # 对id进行base64编码
            id = base64.b64encode(sid.encode('utf-8')).decode('utf-8')
            del_res = requests.request("POST", delete_url + id, headers=headers, data=payload)
            print('删除', sid, '结果', del_res.status_code, ',第', del_file_count, '个,',
                  '%.2f' % (del_file_size_byte / 1024 / 1024), 'M')
    except Exception as e:
        # 获取异常堆栈信息
        except_msg = traceback.format_exc()
        except_msgs.append(except_msg)
        print(except_msg)
print('===删除', bucket, prefix, '下的文件', del_file_count, '个, 总计', '%.2f' % (del_file_size_byte / 1024 / 1024), 'M===')
print('异常信息', except_msgs)

单线程太慢,写了个多线程的,但自己用的时候注意控制下速率,操作太频繁会导致/api/kodov2/rsf/list 返回空items

import requests
import base64
import traceback
import threading
import time

# 请用网页端的登录信息更新headers
headers = {
    'authority':
        'portal.qiniu.com',
    'dnt':
        '1',
    'x-reqid':
        'abc',
    'Cookie':
        'xxx',
    'User-Agent':
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.62'
}

# 要删除的文件所在的 bucket
bucket = 'hmp-public'
# 要删除的文件目录
prefix = 'sandbox3/channelSetMeal/img/'

base_url = 'https://portal.qiniu.com'
query_url = '{}/api/kodov2/rsf/list?allversion=false&bucket={}&prefix={}&limit=50'.format(base_url, bucket, prefix)
delete_url = '{}/api/proxy/rs/delete/'.format(base_url)

del_file_size_byte = 0
del_file_count = 0
except_msgs = []


def query():
    query_res = requests.request("GET", query_url, headers=headers)
    return query_res


def del_file(item):
    global del_file_size_byte
    global del_file_count
    del_file_size_byte += item['fsize']
    del_file_count += 1
    total_size = '%.2f' % (del_file_size_byte / 1024 / 1024)
    total_count = del_file_count
    sid = 'hmp-public:' + item['key']
    # 对sid进行base64编码
    id = base64.b64encode(sid.encode('utf-8')).decode('utf-8')
    del_res = requests.request("POST", delete_url + id, headers=headers)
    print('删除', sid, '结果', del_res.status_code, ',第', total_count, '个,', total_size, 'M')


def main():
    has_next = True
    while has_next:
        try:
            query_res = query()
            if query_res.status_code != 200:
                break
            items = query_res.json()['items']
            has_next = True if len(items) else False
            if not has_next:
                break
            threads = []
            for item in items:
                t = threading.Thread(target=del_file, args=(item,))
                threads.append(t)
                time.sleep(0.1)
                t.start()
            for t in threads:
                t.join()
        except Exception as e:
            # 获取异常堆栈信息
            except_msg = traceback.format_exc()
            except_msgs.append(except_msg)
            print(e)
            print(except_msg)
    print('===删除', bucket, prefix, '下的文件', del_file_count, '个, 总计', '%.2f' % (del_file_size_byte / 1024 / 1024), 'M===')
    print('异常信息', except_msgs)


if __name__ == '__main__':
    main()