1. 程式人生 > >10分鐘內教你用Python實現多個檔案自動上傳到百度雲

10分鐘內教你用Python實現多個檔案自動上傳到百度雲

一、環境說明

Python 3.7  和 win10系統

 

二、準備工作

首先我們需要安裝一個包,在cmd命令列介面安裝 bypy包。

pip install bypy

然後安裝成功後,在命令列執行命令

bypy info

會彈出一些類似一下的介面,要求授權系統認證。不過因為我已經安裝了,所以下面是顯示我的網盤容量和現有量。具體的認證是在瀏覽器中輸入命令列介面中的一行百度雲連結,進入授權介面,複製授權碼,重新回到命令列輸入授權碼。重新輸入bypy info 就可以認證成功了。

登入百度網盤,就可以看到出現了下列的資料夾。由於API限制,所有檔案只能存在該資料夾中。

 

三、程式碼部分

該bypy包快速上手只要三步:建立物件;建立資料夾,上傳檔案。

# 獲取一個bypy物件,封裝了所有百度雲檔案操作的方法
bp = ByPy()

# 百度網盤建立遠端資料夾
bp.mkdir(remotepath = 'dir_name')

# 上傳某一檔案到百度雲網盤對應的遠端資料夾
# ondup中引數代表複製檔案,預設值為'overwrite',指定'newcopy'不會覆蓋重複檔案
bp.upload(localpath= file["fileName"], remotepath= 'dir_name', ondup='newcopy')

利用這些性質,我寫了一份程式碼,功能是將程式碼所在的上層資料夾以內的所有檔案按原來的資料夾組織形式上傳到百度雲中。也就是說,如果你要上傳一個資料夾內的所有檔案,那麼你可以把這份程式碼拷貝到資料夾裡面,然後直接執行就會自動上傳了。

程式碼如下:

from bypy import ByPy
import os
import time
import datetime
import threading

# 百度雲存放檔案的資料夾名
dir_name = "ByPy-test"

# 獲取一個bypy物件,封裝了所有百度雲檔案操作的方法
bp = ByPy()
# 百度網盤建立遠端資料夾bypy-test
bp.mkdir(remotepath = dir_name)

# 函式作用:檔案中的 \ 改為 /
# 函式輸入:檔案絕對路徑
# 輸出:檔案絕對路徑新增轉義符後的結果
def changePath(filePath):
	path = ""
	for i in range(len(filePath)):
		if filePath[i] != "\\":
			path += filePath[i]
		else:
    		 path += "/"
	return path

# 根據當前路徑和資料夾路徑得到相對路徑
def relPath(filePath, topDir):
	relativepath = ""
	for i in range(len(filePath)):
		if i < len(topDir) and filePath[i] == topDir[i]:
			continue
		relativepath += filePath[i]
	#print ("相對路徑" + relativepath)
	return relativepath

# 函式作用:給出資料夾,得到所有檔案的絕對路徑
# 輸入引數:當前資料夾的絕對路徑
# 返回值:一個包含所有檔案絕對路徑,以及檔案所在資料夾的大小的列表
def getFileList(file_dir):    
	fileList = []
	top_dir = ""
	checkFlag = False
	for root, dirs, files in os.walk(file_dir):
		#print(root) #當前目錄路徑  
		if checkFlag == False:
			top_dir = root
			checkFlag = True		
		#print(dirs) #當前路徑下所有子目錄  
		#print(files) #當前路徑下所有非目錄子檔案  
		for file in files: 
			fileDict = dict(Path = changePath(relPath(root, top_dir)), fileName = file, createFlag = False)
			fileList.append(fileDict) # 當前目錄+檔名
			#print(fileDict)
	return fileList

#獲取檔案的大小,結果保留兩位小數,單位為MB
def get_FileSize(filePath):
    fsize = os.path.getsize(filePath)
    fsize = fsize/float(1024*1024)
    return round(fsize,2)

# 獲取檔案絕對路徑列表
allFiles = getFileList(os.path.abspath('.'))

totalFileSize = 0  # 檔案大小變數

start = datetime.datetime.now()   # 計時開始

# 逐個上傳
createFlag = {}
for file in allFiles:
	#bp.upload(localpath=file, remotepath=dir_name, ondup='newcopy')
	print("正在上傳檔案:" + file["fileName"])
	
	if file["Path"] != "":
		bp.mkdir(remotepath = dir_name + file["Path"])
		DIR_NAME = dir_name +  file["Path"]
		bp.upload(localpath= "." + file["Path"]+ "/" +file["fileName"], remotepath = str(DIR_NAME), ondup='newcopy')
		print ("檔案傳送完成:本地路徑:" +  file["Path"]+"/" +file["fileName"] + " 遠端資料夾:" + DIR_NAME)
		totalFileSize += get_FileSize( "." + file["Path"]+ "/" +file["fileName"])
	else:		
		bp.upload(localpath= file["fileName"], remotepath= dir_name, ondup='newcopy')
		print ("檔案傳送完成:" + file["fileName"] + " 遠端資料夾:" + dir_name)
		totalFileSize += get_FileSize( "." + file["Path"]+ "/" +file["fileName"])
	print ("------------------------------------")
end = datetime.datetime.now()  # 計時結束

print("上傳檔案總大小為" + str(totalFileSize) + "MB")
print("花費時間(s):" + str((end - start).seconds))
print("\nupload ok")

 

傳輸速度還是可以的!

 

四、優化

1. 或許可以考慮一下多執行緒,或者多程序傳送,在檔案較大較多的時候,傳輸時間會少挺多的。

2. 可以統計檔案的修改時間,按時間段來發送檔案,達到區域性更新的效果。

 

五、最後

emmm至於你說為啥放著客戶端不用,寫個鬼命令列,(⊙﹏⊙)好像也有道理哦,不過寫著玩唄。寫程式多好玩。

thx for reading.