用smb 获取远程公共盘中word文件。并根据后缀doc/docx 分类保存到本地
因为python docx不能直接读doc后缀的文件,利用win32com将doc文件转换成docx文件,以便用python docx 直接读取解析。
最后将下载下来的中间文件删除
from smb.SMBConnection import SMBConnection ## 链接公共盘服务器
from win32com import client as wc #这个package 只能在windows使用
import os #用于获取目标文件所在路径
import json
import docx
from docx import Document
def save_doc_to_docx(rawpath): # doc转docx
'''
:param rawpath: 传入和传出文件夹的路径
:return: 这一轮copy and 转存结果生成几份docx文件
'''
docx_path=rawpath[:-1]+'x\\'
word = wc.Dispatch("Word.Application")
# 不能用相对路径
# 需要处理的文件所在文件夹目录
filenamelist = os.listdir(rawpath)
for i in os.listdir(rawpath):
i
# 找出文件中以.doc结尾并且不以~$开头的文件(~$是为了排除临时文件的)
if i.endswith('.doc') and (not i.startswith('~$')):
print(i)
# 打开文件
##有些文件可能打开有问题
try:
doc = word.Documents.Open(rawpath + i)
# # 将文件名与后缀分割
# rename = os.path.splitext(i)
# # 将文件另存为.docx
# doc.SaveAs(path + rename[0] + '.docx', 12) # 12表示docx格式
doc.SaveAs("{}x".format(docx_path + i), 12)
doc.Close()
except:
pass
word.Quit()
filenamelist_docx = os.listdir(docx_path)
docx_lt=[]
for file in filenamelist_docx:
if file.endswith(".docx") and (not file.startswith('~$')):
docx_lt.append(file)
return docx_lt
def ConnectShare():
## 用smb 链接获取公共盘中文件并下载文件到本地
host = config['host']
username = config['username']
password = config['password'] # 个人帐户密码,要有公盘权限,假如个人帐户密码改了,必须要改。
conn = SMBConnection(username, password, "", 要链接的公盘的ip地址, is_direct_tcp = True)
assert conn.connect(host, 445)
f_names=[]
f_names_doc= []
f_names_docx= []
for e in conn.listPath(需要链接的公盘最外层文件夹名eg:ASSP,需要链接的公盘路径(不要带上最外层的)eg:/WAPI/xxx一部/doc): ## 完整路径位ASSP/WAPI/xxx一部/doc
# print(e.filename)
# 需要获取word 文件 并且需要过滤临时文件,临时文件通常以~$开头
if e.filename.endswith(".doc") and not e.filename.startswith('~$'):
f_names_doc.append(e.filename)
f_names.append(e.filename)
elif e.filename.endswith(".docx") and not e.filename.startswith('~$'):
f_names_docx.append(e.filename)
f_names.append(e.filename)
## doc 和docx 结尾文件分开读,docx可以直接打开,doc需要进行转换
##将doc文件存到本地doc文件夹内
for file in f_names_doc:
if file.endswith(".doc"):
try:
f = open(r'D:/user/doc/'+file,'wb') ##本地地址 要修改
conn.retrieveFile(需要链接的公盘最外层文件夹名,需要链接的公盘路径+file,f) #它会把文件写在f里面
f.close()
except:
pass
##将docx文件存到本地docx文件夹内
for file in f_names_docx:
if file.endswith(".docx"):
try:
f = open(r'D:/user/docx/'+file,'wb') ##本地地址 要修改
conn.retrieveFile(需要链接的公盘最外层文件夹名,需要链接的公盘路径+file,f) #它会把文件写在f里面
f.close()
except:
pass
## 将doc 转存为docx 并存在 docx文件夹内
path='D:\\user\\doc' # 文件夹绝对路径 本地地址
files=[]
for file in os.listdir(path):
if file.endswith(".doc"): #排除文件夹内的其它干扰文件,只获取".doc"后缀的word文件
files.append(path+'\\'+file)
rawpath=path+'\\'
docx_lt=save_doc_to_docx(rawpath)
num_docx=len(docx_lt)
num_share=len(f_names)
## 共享盘上的文件数量和download的数量相等
if num_docx==num_share:
print('Success, all rd1 has been download!')
## 数量不相等 看哪些文件没有被download 下来
else:
diff_lt=[]
for file in f_names:
file=file.replace("docx","doc")
file=file.replace("doc","docx")
if file not in docx_lt:
diff_lt.append(file)
else:
pass
if diff_lt!=[]:
miss_files=','.join(diff_lt)
print('The following files download failed:'+miss_files)
else:
pass
return docx_lt
def del_file(path):
## 每次跑完都清空文件夹
ls = os.listdir(path)
for i in ls:
c_path = os.path.join(path, i)
if os.path.isdir(c_path):
del_file(c_path)
else:
os.remove(c_path)