第8章 基于文件和設(shè)備的數(shù)據(jù)采集_第1頁(yè)
第8章 基于文件和設(shè)備的數(shù)據(jù)采集_第2頁(yè)
第8章 基于文件和設(shè)備的數(shù)據(jù)采集_第3頁(yè)
第8章 基于文件和設(shè)備的數(shù)據(jù)采集_第4頁(yè)
第8章 基于文件和設(shè)備的數(shù)據(jù)采集_第5頁(yè)
已閱讀5頁(yè),還剩67頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第8章基于文件和設(shè)備的數(shù)據(jù)采集董付國(guó)微信公眾號(hào):Python小屋本章學(xué)習(xí)目標(biāo)了解文件的概念與常見文件類型的擴(kuò)展名理解文本文件與二進(jìn)制文件的概念與區(qū)別熟練掌握內(nèi)置函數(shù)open()的用法理解并熟練應(yīng)用內(nèi)置函數(shù)open()的mode參數(shù)與encoding參數(shù)熟練掌握從文本文件中讀取數(shù)據(jù)的方法熟練掌握上下文管理語(yǔ)句with的用法熟練掌握os、os.path、shutil模塊的使用熟練掌握從Word、Excel、PowerPoint、PDF等類型文件中讀取數(shù)據(jù)的方法了解從圖像、視頻、音頻等類型文件中采集數(shù)據(jù)的相關(guān)技術(shù)了解從麥克風(fēng)、攝像頭、溫度/濕度傳感器等設(shè)備中采集數(shù)據(jù)的相關(guān)技術(shù)8.1文本文件與二進(jìn)制文件內(nèi)容操作文件是長(zhǎng)久保存信息并支持重復(fù)使用和反復(fù)修改的重要方式,同時(shí)也是信息交換的重要途徑之一。記事本文件、日志文件、各種配置文件、數(shù)據(jù)庫(kù)文件、圖形圖像文件、音頻視頻文件、可執(zhí)行文件、Office文檔、動(dòng)態(tài)鏈接庫(kù)文件等等,都以不同的形式存儲(chǔ)在各種存儲(chǔ)設(shè)備(如硬盤、U盤、光盤、云盤、網(wǎng)盤等等)上。8.1文本文件與二進(jìn)制文件內(nèi)容操作按內(nèi)容讀寫方式的不同,可以把文件分為文本文件和二進(jìn)制文件兩大類。(1)文本文件文本文件可以使用記事本、Notepad++、vim、gedit、ultraedit、Emacs、SublimeText3、IDLE或類似軟件自動(dòng)識(shí)別編碼格式并直接進(jìn)行顯示和編輯,人類能夠直接閱讀和理解。文本文件由若干文本行組成,每行以換行符結(jié)束,文件中包含英文字母、漢字、數(shù)字字符、標(biāo)點(diǎn)符號(hào)等。擴(kuò)展名為txt、log、ini、c、cpp、h、py、pyw、html、js、css、csv、json的文件都屬于文本文件。(2)二進(jìn)制文件數(shù)據(jù)庫(kù)文件、圖形圖像文件、可執(zhí)行文件、動(dòng)態(tài)鏈接庫(kù)文件、音頻文件、視頻文件、Office文檔等均屬于二進(jìn)制文件。二進(jìn)制文件無(wú)法用記事本或其他普通字處理軟件正常進(jìn)行顯示和編輯,人類也無(wú)法直接閱讀和理解,需要使用正確的軟件進(jìn)行解碼或反序列化之后才能正確地讀取、顯示、修改或執(zhí)行。二進(jìn)制文件的擴(kuò)展名非常多,例如docx、xlsx、pptx、dat、exe、dll、pyd、so、mp4、bmp、png、jpg、rm、rmvb、avi、db、sqlite、mp3、wav、ogg、m4a。8.1.1內(nèi)置函數(shù)open()Python內(nèi)置函數(shù)open()使用指定的模式和編碼格式打開指定文件,完整語(yǔ)法為:open(file,mode='r',buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)主要參數(shù)含義如下:參數(shù)file指定要操作的文件名稱,如果該文件不在當(dāng)前文件夾或子文件夾中,建議使用絕對(duì)路徑,確保從當(dāng)前工作文件夾出發(fā)可以訪問(wèn)到該文件。為了減少路徑中分隔符“\”的輸入,可以使用原始字符串。參數(shù)mode指定打開文件后的處理方式,或者說(shuō)打開文件以后要做什么。參數(shù)buffering指定緩存模式,-1表示由操作系統(tǒng)自動(dòng)維護(hù)緩存,0表示不使用緩存(僅適用于二進(jìn)制模式),1表示行緩存模式(僅適用于文本模式),大于1的整數(shù)表示設(shè)置緩存大小。參數(shù)encoding指定對(duì)文本進(jìn)行編碼和解碼的方式,只適用于文本模式。默認(rèn)值None表示依賴于具體的操作系統(tǒng),在Windows操作系統(tǒng)中默認(rèn)使用UTF-8編碼格式。8.1.1內(nèi)置函數(shù)open()如果執(zhí)行成功,open()函數(shù)返回1個(gè)文件對(duì)象,然后通過(guò)這個(gè)文件對(duì)象的方法可以對(duì)文件進(jìn)行讀寫操作,最后調(diào)用文件對(duì)象的close()方法關(guān)閉文件。如果指定的文件路徑不存在、訪問(wèn)權(quán)限不夠、磁盤空間不夠或其他原因?qū)е聞?chuàng)建文件對(duì)象失敗則拋出IOError異常。對(duì)文件內(nèi)容操作完以后,一定要關(guān)閉文件。然而,即使我們寫了關(guān)閉文件的代碼,也無(wú)法保證文件一定能夠正常關(guān)閉。例如,如果在打開文件之后和關(guān)閉文件之前的代碼發(fā)生錯(cuò)誤導(dǎo)致程序崩潰,這時(shí)文件就無(wú)法正常關(guān)閉。在管理文件對(duì)象時(shí)推薦使用with關(guān)鍵字,可以避免這個(gè)問(wèn)題。8.1.2文件對(duì)象常用方法方法功能說(shuō)明close()把寫緩沖區(qū)的內(nèi)容寫入文件,關(guān)閉文件read(size=-1,/)從以'r'、'r+'模式打開的文本文件中讀取并返回最多size個(gè)字符,或從以'rb'、'rb+'模式打開的二進(jìn)制文件中讀取并返回最多size個(gè)字節(jié),參數(shù)size的默認(rèn)值-1表示讀取文件中全部?jī)?nèi)容。每次讀取時(shí)從文件指針當(dāng)前位置開始讀,讀取完成后自動(dòng)修改文件指針到讀取結(jié)束的下一個(gè)位置readline(size=-1,/)參數(shù)size=-1時(shí)從以'r'、'r+'模式打開的文本文件中讀取當(dāng)前位置開始到下一個(gè)換行符(包含)之前的所有內(nèi)容,如果當(dāng)前已經(jīng)到達(dá)文件尾就返回空字符串。如果參數(shù)size為正整數(shù)則讀取當(dāng)前位置開始到下一個(gè)換行符(包含)之間的最多size個(gè)字符,指定其他任意負(fù)整數(shù)時(shí)都與-1等價(jià)。每次讀取時(shí)從文件指針當(dāng)前位置開始讀,讀取完成后自動(dòng)修改文件指針到讀取結(jié)束的下一個(gè)位置readlines(hint=-1,/)參數(shù)hint=-1時(shí)從以'r'、'r+'模式打開的文本文件中讀取所有內(nèi)容,返回包含每行字符串的列表;參數(shù)hint為正整數(shù)時(shí)從當(dāng)前位置開始讀取若干連續(xù)完整的行,如果已讀取的字符數(shù)量超過(guò)hint的值就停止讀取seek(cookie,whence=0,/)定位文件指針,把文件指針移動(dòng)到相對(duì)于whence的偏移量為cookie字節(jié)的位置。其中whence為0表示文件頭,1表示當(dāng)前位置,2表示文件尾。對(duì)于文本文件,whence=2時(shí)cookie必須為0;對(duì)于二進(jìn)制文件,whence=2時(shí)cookie可以為負(fù)數(shù)。不論以文本模式還是二進(jìn)制模式打開文件,都是以字節(jié)為單位進(jìn)行定位write(text,/)把text的內(nèi)容寫入文件,如果寫入文本文件則text應(yīng)該是字符串,如果寫入二進(jìn)制文件則text應(yīng)該是字節(jié)串。返回寫入字符串或字節(jié)串的長(zhǎng)度writelines(lines,/)把列表lines中的所有字符串寫入文本文件,并不在lines中每個(gè)字符串后面自動(dòng)增加換行符。如果確實(shí)想讓lines中的每個(gè)字符串寫入文本文件之后各占一行,應(yīng)由程序員保證每個(gè)字符串都以換行符結(jié)束8.1.3上下文管理語(yǔ)句with在實(shí)際開發(fā)中,讀寫文件應(yīng)優(yōu)先考慮使用上下文管理語(yǔ)句with來(lái)管理文件對(duì)象,這會(huì)減少很多麻煩,代碼也更加簡(jiǎn)潔。關(guān)鍵字with可以自動(dòng)管理資源,不論因?yàn)槭裁丛蛱鰓ith塊,總能保證資源被正確關(guān)閉。除了用于文件操作,with關(guān)鍵字還可以用于數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)連接或類似場(chǎng)合。用于文件內(nèi)容讀寫時(shí),with語(yǔ)句的語(yǔ)法形式如下:withopen(filename,mode,encoding,...)asfp:#這里寫通過(guò)文件對(duì)象fp讀寫文件內(nèi)容的代碼8.1.4文本文件操作例題解析例8-1已知文件“商場(chǎng)一樓手機(jī)信號(hào)強(qiáng)度.txt”中保存了某商場(chǎng)平面圖部分位置的手機(jī)信號(hào)強(qiáng)度測(cè)量結(jié)果,每行表示一個(gè)測(cè)量位置的x、y坐標(biāo)和信號(hào)強(qiáng)度,其中x、y坐標(biāo)以商場(chǎng)西南角為坐標(biāo)原點(diǎn),向東為x正軸,向北為y正軸。文件內(nèi)容格式如下,0,0,600,3,705,0,6810,0,73編寫程序,讀取該文件內(nèi)容,輸出信號(hào)最弱和最強(qiáng)的所有位置的坐標(biāo)和信號(hào)強(qiáng)度。8.1.4文本文件操作例題解析fn='商場(chǎng)一樓手機(jī)信號(hào)強(qiáng)度.txt'withopen(fn,encoding='utf8')asfp:data=fp.readlines()data=list(map(lambdaline:list(map(int,line.split(','))),data))max_value=max(data,key=lambdaline:line[2])[2]min_value=min(data,key=lambdaline:line[2])[2]max_position=list(filter(lambdaline:line[2]==max_value,data))min_position=list(filter(lambdaline:line[2]==min_value,data))print('信號(hào)最弱的位置及強(qiáng)度:',*min_position,sep='\n')print('信號(hào)最強(qiáng)的位置及強(qiáng)度:',*max_position,sep='\n')8.1.4文本文件操作例題解析例8-2編寫程序,讀取并輸出Python安裝目錄中文本文件news.txt的所有行內(nèi)容。withopen('news.txt',encoding='utf8')asfp:forlineinfp:print(line)8.1.4文本文件操作例題解析例8-3編寫程序,提取.ipynb格式文件中的Python代碼并保存為.py格式的文件。importjsonwithopen('Pandas數(shù)據(jù)分析實(shí)戰(zhàn).ipynb',encoding='utf8')asfp:content=json.load(fp)

withopen('program.py','w',encoding='utf8')asfp:foritemincontent['cells']:fp.writelines([i.rstrip()+'\n'foriinitem['source']])8.1.4文本文件操作例題解析例8-4已知文件“手機(jī)用戶通話記錄.csv”中的內(nèi)容格式如下,用戶名,開始通話時(shí)間,通話時(shí)長(zhǎng)(秒)user897,2020-07-0100:00:00,828user771,2020-07-0100:13:34,2677user928,2020-07-0100:17:12,1073編寫程序,讀取文件內(nèi)容并統(tǒng)計(jì)指定時(shí)間段通話總時(shí)長(zhǎng)最多的用戶及通話總時(shí)長(zhǎng)。8.1.4文本文件操作例題解析fromcsvimportreaderfromoperatorimportitemgetterdefmain(flag):#flag=0返回[上午8:00,下午18:00)之間打電話總時(shí)長(zhǎng)最多的用戶名#flag=1返回其他時(shí)間打電話總時(shí)長(zhǎng)最多的用戶名data={}withopen('手機(jī)用戶通話記錄.csv',encoding='utf8')asfp:rd=reader(fp)forindex,rowinenumerate(rd):ifindex==0:continuehour=int(row[1].split()[1][:2])if((flag==0andhourinrange(8,18))or(flag==1andhournotinrange(8,18))):#用戶名user=row[0]#總時(shí)長(zhǎng)data[user]=data.get(user,0)+int(row[2])#升序排序,最后一個(gè)returnsorted(data.items(),key=itemgetter(1))[-1]print(main(0))print(main(1))8.2文件級(jí)與文件夾級(jí)操作os模塊常用函數(shù)函數(shù)功能說(shuō)明chdir(path)把path設(shè)為當(dāng)前工作文件夾getcwd()返回表示當(dāng)前工作文件夾的字符串getcwdb()放回表示當(dāng)前工作文件夾的字節(jié)串listdir(path=None)返回path文件夾中的文件和子文件夾名字組成的列表,path默認(rèn)值None表示當(dāng)前文件夾mkdir(path,mode=511,*,dir_fd=None)創(chuàng)建文件夾,在Windows平臺(tái)上mode參數(shù)無(wú)效rmdir(path,*,dir_fd=None)刪除path指定的文件夾,要求其中不能有文件或子文件夾remove(path,*,dir_fd=None)刪除指定的文件,要求用戶擁有刪除文件的權(quán)限,并且文件沒(méi)有只讀或其他特殊屬性rename(src,dst,*,src_dir_fd=None,dst_dir_fd=None)重命名文件或文件夾startfile(filepath[,operation])使用關(guān)聯(lián)的應(yīng)用程序打開指定文件或啟動(dòng)指定應(yīng)用程序,如果參數(shù)filepath指定的是URL,會(huì)自動(dòng)使用默認(rèn)瀏覽器打開這個(gè)地址stat(path,*,dir_fd=None,follow_symlinks=True)查看文件的屬性,包括創(chuàng)建時(shí)間、最后訪問(wèn)時(shí)間、最后修改時(shí)間、大小等等8.2文件級(jí)與文件夾級(jí)操作os.path模塊常用函數(shù)函數(shù)功能說(shuō)明abspath(path)返回給定路徑的絕對(duì)路徑basename(p)返回指定路徑的最后一個(gè)路徑分隔符后面的部分,例如basename(r'C:\Python310\python.exe')的值為'python.exe'dirname(p)返回給定路徑的最后一個(gè)路徑分隔符前面的部分,例如dirname(r'C:\Python310\python.exe')的值為'C:\\Python310'exists(path)判斷指定的路徑是否存在,返回True或Falsegetatime(filename)返回表示文件最后訪問(wèn)時(shí)間的紀(jì)元秒數(shù)(從格林尼治時(shí)間1970年1月1日0時(shí)0分0秒開始計(jì)算,經(jīng)過(guò)的秒數(shù))getctime(filename)返回表示文件創(chuàng)建時(shí)間(Windows)或元數(shù)據(jù)最后修改時(shí)間(Unix)的紀(jì)元秒數(shù)getmtime(filename)返回表示文件最后修改時(shí)間的紀(jì)元秒數(shù)getsize(filename)返回文件的大小,單位為字節(jié)isdir(s)判斷指定的路徑是否為文件夾,返回True或Falseisfile(path)判斷指定的路徑是否為文件,返回True或Falsejoin(path,*paths)連接兩個(gè)或多個(gè)path,相鄰路徑之間插入路徑分隔符,返回連接后的字符串8.2文件級(jí)與文件夾級(jí)操作importos.pathaspathfromdatetimeimportdatetimefn=r'E:\Python310\Python.exe'ctime=path.getctime(fn)atime=path.getatime(fn)mtime=path.getmtime(fn)print(ctime,atime,mtime,sep=',')func=lambdat:str(datetime.fromtimestamp(t))[:19]print(*map(func,[ctime,atime,mtime]),sep=',')運(yùn)行結(jié)果為:1659362398.0,1660547290.5947957,1659362398.02022-08-0121:59:58,2022-08-1515:08:10,2022-08-0121:59:588.2文件級(jí)與文件夾級(jí)操作例8-5編寫程序,按照深度優(yōu)先的順序遞歸遍歷并輸出指定文件夾的目錄樹結(jié)構(gòu),包括所有文件及其所有子文件夾中的文件名。fromosimportlistdirfromos.pathimportjoin,isfile,isdirdeflistDirDepthFirst(directory):#遍歷文件夾,如果是文件就直接輸出#如果是文件夾,就輸出顯示,然后遞歸遍歷該文件夾forsubPathinlistdir(directory):path=join(directory,subPath)ifisfile(path):print(path)elifisdir(path):print(path)listDirDepthFirst(path)listDirDepthFirst(r'D:\\')8.2文件級(jí)與文件夾級(jí)操作例8-6編寫程序,按照廣度優(yōu)先的順序遍歷并輸出指定文件夾的目錄樹結(jié)構(gòu),包括所有文件及其所有子文件夾中的文件名。fromosimportlistdir,getcwdfromos.pathimportjoin,isdirdeflistDirWidthFirst(directory):dirs=[directory]#如果還有沒(méi)遍歷過(guò)的文件夾,繼續(xù)循環(huán)whiledirs:#遍歷需要遍歷但還沒(méi)遍歷過(guò)的第一項(xiàng)current=dirs.pop(0)#遍歷該文件夾,如果是文件就直接輸出顯示#如果是文件夾,輸出顯示后,追加到列表尾部表示這是需要遍歷的文件夾forsubPathinlistdir(current):path=join(current,subPath)print(path)ifisdir(path):#記下這個(gè)文件夾,后面再處理其中的文件和子文件夾dirs.append(path)listDirWidthFirst(getcwd())8.3Word、Excel、PowerPoint、PDF文件內(nèi)容讀取

8.3.1docx、xlsx、pptx文件操作基礎(chǔ)擴(kuò)展庫(kù)python-docx、docx2python等提供了docx格式Word文檔操作的接口。擴(kuò)展庫(kù)python-docx可以使用pipinstallpython-docx命令進(jìn)行安裝,安裝之后叫docx。擴(kuò)展庫(kù)docx2python的安裝名稱和使用名稱是一致的。在docx文件中,有很多sections(節(jié))、paragraphs(段落)、tables(表格)、inline_shapes(行內(nèi)元素)組成,其中每個(gè)段落又包括一個(gè)或多個(gè)run(一段連續(xù)的具有相同樣式的文本),每個(gè)表格又包含一個(gè)或多個(gè)rows(行)和columns(列),每行或列又包括多個(gè)cells(單元格)。所有這些對(duì)象都具有大量的屬性,通過(guò)這些屬性來(lái)讀取或控制Word文檔中的內(nèi)容和格式。8.3.1docx、xlsx、pptx文件操作基礎(chǔ)Python擴(kuò)展庫(kù)openpyxl提供了操作xlsx格式Excel文件的接口,可以使用pipinstallopenpyxl安裝。每個(gè)Excel文件稱為一個(gè)workbook(工作簿),由若干worksheet(工作表)組成,每個(gè)工作表又由若干rows(行)和columns(列)組成,每個(gè)行和列由若干單元格組成。在單元格中可以存儲(chǔ)整數(shù)、實(shí)數(shù)、字符串、公式、圖表等對(duì)象。8.3.1docx、xlsx、pptx文件操作基礎(chǔ)Python擴(kuò)展庫(kù)python-pptx提供了pptx格式PowerPoint文件操作的接口,可以使用pipinstallpython-pptx命令安裝,安裝之后的名字叫pptx。每個(gè)PowerPoint文件稱為一個(gè)Presentation(演示文檔),每個(gè)Presentation對(duì)象包含一個(gè)由所有幻燈片組成的屬性slides,每個(gè)幻燈片對(duì)象的屬性Shapes包含了這一頁(yè)幻燈片上的所有元素,可以是TEXT_BOX(文本框)、PICTURE(圖片)、CHART(圖表)、TABLE(表格)或其他等元素,分別對(duì)應(yīng)不同的shape_type屬性值。8.3.2Word文件操作例8-7編寫程序,檢查word文檔的連續(xù)重復(fù)字,例如“用戶的的資料”或“需要需要用戶輸入”之類的情況。fromdocximportDocumentdoc=Document('董付國(guó)《Python網(wǎng)絡(luò)程序設(shè)計(jì)》.docx')contents=''.join((p.textforpindoc.paragraphs))words=set()forindex,chinenumerate(contents[:-2]):

word=contents[index:index+3]if(chinword[1:])and

(wordnotinwords):words.add(word)print(word)8.3.2Word文件操作例8-8編寫程序,提取docx格式的教材電子版中例題、插圖和表格清單。本例代碼中使用到了正則表達(dá)式模塊re,其中的函數(shù)match()用來(lái)檢查目標(biāo)字符串是否匹配特定的模式,在正則表達(dá)式中'\d'可以匹配單個(gè)任意阿拉伯?dāng)?shù)字字符,'\d+'用來(lái)匹配一個(gè)或任意多個(gè)連續(xù)的阿拉伯?dāng)?shù)字字符。8.3.2Word文件操作importrefromdocximportDocumentresult={'li':[],'fig':[],'tab':[]}doc=Document(r'董付國(guó)《Python程序設(shè)計(jì)與數(shù)據(jù)采集》.docx')forpindoc.paragraphs:#遍歷文檔所有段落t=p.text#獲取每一段的文本ifre.match('例\d+-\d+',t):#例題result['li'].append(t)elifre.match('圖\d+-\d+',t):#插圖result['fig'].append(t)elifre.match('表\d+-\d+',t):#表格result['tab'].append(t)forkeyinresult.keys():#輸出結(jié)果print('='*30)forvalueinresult[key]:print(value)8.3.2Word文件操作例8-9編寫程序,查找并輸出docx格式的文檔中所有紅色字體和加粗的文字。fromdocximportDocumentfromdocx.sharedimportRGBColorboldText,redText=[],[]doc=Document('帶有加粗和紅色字體的文檔.docx')forpindoc.paragraphs:forrinp.runs:ifr.bold:#加粗字體boldText.append(r.text)ifr.font.color.rgb==RGBColor(255,0,0):#紅色字體redText.append(r.text)result={'redtext':redText,'boldtext':boldText,'both':set(redText)&set(boldText)}fortitleinresult.keys():print(title.center(30,'='))fortextinresult[title]:print(text)8.3.2Word文件操作例8-10編寫程序,提取docx文檔中所有嵌入式圖片和浮動(dòng)圖片。使用python-docx擴(kuò)展庫(kù)提取圖片比較繁瑣,可以安裝和使用另一個(gè)擴(kuò)展庫(kù)docx2python來(lái)完成這個(gè)任務(wù)。fromdocx2pythonimportdocx2pythonobj=docx2python('包含圖片的文檔.docx')forname,imageDatainobj.images.items():withopen(name,'wb')asfp:fp.write(imageData)8.3.2Word文件操作例8-11編寫程序,提取docx文檔所有超鏈接文本和地址。代碼一(適用于WPS創(chuàng)建的docx格式文檔):fromdocximportDocumentd=Document('帶超鏈接的文檔(WPS).docx')forpind.paragraphs:forindex,runinenumerate(p.runs):ifnotrun.text:continueif=='Hyperlink':print(run.text,end=':')forchildinp.runs[index-2].element.getchildren():text=child.textiftextandtext.startswith('HYPERLINK'):print(text[12:-2])8.3.2Word文件操作代碼二(適用于Word創(chuàng)建的docx格式文檔):fromreimportfindallfromzipfileimportZipFilewithZipFile('帶超鏈接的文檔(Word版).docx')aszf:#提取資源IDcontent=zf.read('word/document.xml').decode()#這個(gè)正則表達(dá)式中有2個(gè)模式,模式0是整個(gè)正則表達(dá)式,模式1是IDpattern=r'(<w:hyperlink.+?r:id="(.+?)".+?</w:hyperlink>)'#findall()只返回圓括號(hào)里的內(nèi)容pairs=findall(pattern,content)content=zf.read('word/_rels/document.xml.rels').decode()forpairinpairs:#根據(jù)ID提取對(duì)應(yīng)的超鏈接地址pattern=f'<RelationshipId="{pair[1]}".*?Target="(.+?)"'target=findall(pattern,content)[0]#超鏈接文本可能在多個(gè)run中,連接到一起pattern='<w:t>(.+?)</w:t>'txt=''.join(findall(pattern,pair[0]))print(txt,target,sep=':')8.3.2Word文件操作例8-12編寫程序,讀取并輸出docx文檔中所有標(biāo)題。fromdocximportDocumentobj=Document('包含標(biāo)題的文檔.docx')forpinobj.paragraphs:style_name=ifstyle_name.startswith('Heading'):print(style_name,p.text,sep=':')8.3.2Word文件操作例8-13編寫程序,讀取并輸出docx文檔中文本框里的文本。fromdocximportDocumentfilename=r'帶文本框的測(cè)試文件.docx'document=Document(filename)#遍歷文檔每個(gè)子節(jié)點(diǎn)forchildindocument.element.body.iter():#只處理textboxifchild.tag.endswith('textbox'):print(f'\n{"="*20}',end='')#遍歷文本框中每個(gè)子節(jié)點(diǎn)forcinchild.iter():c_tag=c.tag#遇到段落,換行ifc_tag.endswith('main}pPr'):print()#遇到段內(nèi)run,提取并輸出文本elifc_tag.endswith('main}r'):print(c.text,end='')8.3.2Word文件操作例8-14編寫程序,讀取并輸出docx文檔中的所有批注。fromreimportfindallfromzipfileimportZipFilefn=r'帶批注的測(cè)試文件.docx'withZipFile(fn)asfp:try:content=fp.read('word/comments.xml').decode('utf8')except:content=''ifnotcontent:print('這個(gè)文檔沒(méi)有批注')else:forcommentinfindall(r'<w:t>(.*?)</w:t>',content):print(comment)8.3.2Word文件操作例8-15編寫程序,查找并輸出docx文檔中包含字體種類最多的一段文本。fromdocximportDocumentdefmain(fn):doc=Document(fn)fonts={}forparagraphindoc.paragraphs:text=paragraph.textfonts[text]=set()forruninparagraph.runs:fonts[text].add()fonts=sorted(fonts.items(),key=lambdaitem:len(item[1]))returnfonts[-1][0]print(main('不同字體的文本.docx'))8.3.2Word文件操作例8-16編寫程序,讀取并輸出docx文檔中所有腳注文本。importwin32clipboardfromwin32comimportclientdefget_footnotes(filename):word=client.Dispatch('Word.Application')doc=word.Documents.Open(filename)print(f'=========={filename}中的腳注')forfoot_noteindoc.Footnotes:r=doc.Range(foot_note.Reference.Start,foot_note.Reference.End)#把腳注的內(nèi)容復(fù)制到剪貼板r.Copy()#獲取剪貼板中的內(nèi)容win32clipboard.OpenClipboard()fn_text=win32clipboard.GetClipboardData()win32clipboard.EmptyClipboard()win32clipboard.CloseClipboard()#輸出腳注位置的正文文本以及腳注的文本forsinr.Sentences:print(s,end='')print(fn_text)doc.Close()word.Quit()get_footnotes('帶有腳注的文檔.docx')get_footnotes('我是一個(gè)莫得腳注的文檔.docx')8.3.2Word文件操作例8-17編寫程序,統(tǒng)計(jì)docx文檔中除黑色之外使用最多的前3種文本顏色。fromoperatorimportitemgetterfromdocximportDocumentfromdocx.sharedimportRGBColordefmain(fn):word=Document(fn)colors={}#遍歷所有段落forpinword.paragraphs:#遍歷所有runforrinp.runs:#當(dāng)前run的文本顏色color=r.font.color.rgb#如果沒(méi)有顯式設(shè)置字體顏色,則為Noneifcolornotin(RGBColor(0,0,0),None):colors[color]=colors.get(color,0)+1#按顏色使用次數(shù)降序排序colors=sorted(colors.items(),key=itemgetter(1),reverse=True)#返回元組,包含前3種使用次數(shù)最多的十六進(jìn)制顏色returntuple(map(str,map(itemgetter(0),colors[:3])))print(main('不同顏色的文本.docx'))8.3.3Excel文件操作例8-18編寫程序,讀取“學(xué)生多次考試成績(jī).xlsx”文件中學(xué)生多次參加不同課程的考試數(shù)據(jù),統(tǒng)計(jì)每個(gè)學(xué)生每門課程的最高成績(jī),統(tǒng)計(jì)結(jié)果寫入新文件“學(xué)生每門課程最高分.xlsx”。代碼一(使用擴(kuò)展庫(kù)openpyxl):code\例8-18_1.py8.3.3Excel文件操作代碼二(使用擴(kuò)展庫(kù)Pandas):importpandasaspddefgetResult(oldfile,newfile):df=pd.read_excel(oldfile)df.groupby(['姓名','課程']).max().to_excel(newfile)oldfile=r'學(xué)生多次考試成績(jī).xlsx'newfile=r'學(xué)生每門課程最高分.xlsx'getResult(oldfile,newfile)8.3.3Excel文件操作例8-19文件“電影導(dǎo)演和演員.xlsx”中有三列分別為電影名稱、導(dǎo)演和演員列表(同一個(gè)電影可能會(huì)有多個(gè)演員,每個(gè)演員姓名之間使用中文全角逗號(hào)分隔),如圖8-4所示。編寫程序統(tǒng)計(jì)每個(gè)演員的參演電影分別有哪些、最受歡迎(參演電影數(shù)量最多)的演員名稱以及關(guān)系最好(共同參演電影數(shù)量最多)的兩個(gè)演員。8.3.3Excel文件操作fromitertoolsimportcombinationsfromopenpyxlimportload_workbookdefget_actors(filename):result=dict()#打開xlsx文件,獲取第一個(gè)worksheetws=load_workbook(filename).worksheets[0]#遍歷Excel文件中的所有行forindex,rowinenumerate(ws.rows):#跳過(guò)第一行的表頭ifindex==0:continue#獲取電影名稱和演員列表filmName,actor=row[0].value,row[2].value.split(',')#遍歷該電影的所有演員,統(tǒng)計(jì)參演電影forainactor:#每個(gè)元素的“鍵”為演員名稱,“值”為參演電影名稱的集合result[a]=result.get(a,set())|{filmName}returnresult8.3.3Excel文件操作data=get_actors('電影導(dǎo)演和演員.xlsx')#按演員名稱編號(hào)升序排序,方便查看輸出結(jié)果foriteminsorted(data.items(),key=lambdax:int(x[0][2:])):print(item)print('最受歡迎的演員:',max(data.items(),key=lambdaitem:len(item[1]))[0])defrelations():#演員名單actors=tuple(data.keys())trueLove=[0,()]#選擇法,查找共同參演電影數(shù)量最多的兩個(gè)演員foractor1,actor2incombinations(actors,2):common=len(data[actor1]&data[actor2])ifcommon>trueLove[0]:trueLove=[common,(actor1,actor2)]return('關(guān)系最好的兩個(gè)演員是{0[1]},''Ta們共同主演的電影數(shù)量是{0[0]}'.format(trueLove))print(relations())8.3.3Excel文件操作例8-20編寫程序,輸出Excel文件中單元格中公式計(jì)算結(jié)果。假設(shè)Excel文件中第2個(gè)工作表中第4列為公式。importopenpyxl#打開Excel文件,參數(shù)data_only=True是關(guān)鍵wb=openpyxl.load_workbook('data.xlsx',data_only=True)#獲取WorkSheet,實(shí)際使用時(shí)根據(jù)情況設(shè)置下標(biāo)ws=wb.worksheets[1]forrowinws.rows:print(row[3].value)8.3.3Excel文件操作例8-21編寫程序,批量提取Excel文件中的單元格批注。fromopenpyxlimportload_workbookfn='帶單元格批注的文件.xlsx'ws=load_workbook(fn,data_only=True).worksheets[0]forrowinws.rows:forcellinrow:ifment:print(f'value:{cell.value}\n{str(ment.text)}',end='\n======\n')8.3.3Excel文件操作例8-22安裝擴(kuò)展庫(kù)xlwings,然后編寫程序,批量提取Excel文件中文本框組件中的文本。importxlwingsasxwdefprint_textbox(xlsx_file):#先創(chuàng)建App對(duì)象,在App對(duì)象中打開xlsx文件,最后退出App對(duì)象#如果使用xlwings.Book直接打開xlsx文件,close()之后會(huì)留下一個(gè)空的Excel進(jìn)程#后臺(tái)打開xlsx文件,不自動(dòng)添加空白表格app=xw.App(visible=False,add_book=False)wb=app.books.open(xlsx_file)forsheetinwb.sheets:print('='*10+)forshapeinsheet.shapes:if.startswith('TextBox'):print('='*5+)#文本框里的換行符是\r,改成\n方便輸出print(shape.text.replace('\r','\n'))wb.close()app.quit()

print_textbox('包含文本框的文件.xlsx')8.3.3Excel文件操作例8-23編寫程序,讀取Excel文件中人員信息并根據(jù)身份證號(hào)查找超過(guò)40歲的人。code\例8-23.py8.3.3Excel文件操作例8-24文件“超市營(yíng)業(yè)額.xlsx”中保存了某超市2019年3月1日至5日各員工在不同時(shí)段、不同柜臺(tái)的銷售額。部分?jǐn)?shù)據(jù)如圖8-6所示。編寫程序,讀取該文件中的數(shù)據(jù),統(tǒng)計(jì)每個(gè)員工的銷售總額、每個(gè)時(shí)段的銷售總額、每個(gè)柜臺(tái)的銷售總額。8.3.3Excel文件操作代碼一(使用擴(kuò)展庫(kù)openpyxl):fromopenpyxlimportload_workbook#3個(gè)字典分別存儲(chǔ)按員工、按時(shí)段、按柜臺(tái)的銷售總額persons=dict()periods=dict()goods=dict()ws=load_workbook('超市營(yíng)業(yè)額.xlsx').worksheets[0]forindex,rowinenumerate(ws.rows):#跳過(guò)第一行的表頭ifindex==0:continue#獲取每行的相關(guān)信息,下畫線表示匿名變量,接收但不存儲(chǔ)值,用來(lái)占位_,name,_,time,num,good=map(lambdacell:cell.value,row)#根據(jù)每行的值更新三個(gè)字典persons[name]=persons.get(name,0)+numperiods[time]=periods.get(time,0)+numgoods[good]=goods.get(good,0)+numprint(persons)print(periods)print(goods)8.3.3Excel文件操作代碼二(使用擴(kuò)展庫(kù)Pandas):importpandasaspd#設(shè)置每列對(duì)齊pd.set_option('display.unicode.ambiguous_as_wide',True)pd.set_option('display.unicode.east_asian_width',True)df=pd.read_excel('超市營(yíng)業(yè)額.xlsx')print(df.groupby('姓名').sum().drop(['工號(hào)','日期'],axis=1),end='\n\n')print(df.groupby('時(shí)段').sum().drop(['工號(hào)','日期'],axis=1),end='\n\n')print(df.groupby('柜臺(tái)').sum().drop(['工號(hào)','日期'],axis=1),end='\n\n')8.3.3Excel文件操作例8-25編寫程序,讀取Excel文件中的個(gè)人愛(ài)好,在最后插入一列,對(duì)每個(gè)人的愛(ài)好進(jìn)行匯總。8.3.3Excel文件操作fromopenpyxlimportload_workbookwb=load_workbook('每個(gè)人的愛(ài)好.xlsx')ws=wb.worksheets[0]forindex,rowinenumerate(ws.rows,start=1):ifindex==1:titles=tuple(map(lambdacell:cell.value,row))[1:]lastCol=len(titles)+2ws.cell(row=index,column=lastCol,value='所有愛(ài)好')else:values=tuple(map(lambdacell:cell.value,row))[1:]result=','.join((titles[i]fori,vinenumerate(values)ifv=='是'))ws.cell(row=index,column=lastCol,value=result)wb.save('每個(gè)人的愛(ài)好匯總.xlsx')8.3.3Excel文件操作例8-26編寫程序,隨機(jī)化Excel文件中的學(xué)號(hào)和姓名,進(jìn)行數(shù)據(jù)脫敏。fromrandomimportchoicesfromstringimportascii_letters,digitsfromopenpyxlimportload_workbookwb=load_workbook(r'演示用數(shù)據(jù).xlsx')ws=wb.worksheets[0]last_student=Noneforindex,rowinenumerate(ws.rows,start=1):ifindex==1:continuecurrent_student=[row[0].value,row[1].value]#假設(shè)每個(gè)學(xué)生的信息是連續(xù)存放在一起的ifcurrent_student!=last_student:last_student=current_studentrandom_id=''.join(choices(digits,k=10))random_name=''.join(choices(ascii_letters,k=6))ws['A'+str(index)]=random_idws[f'B{index}']=random_namewb.save(r'脫敏結(jié)果.xlsx')8.3.3Excel文件操作例8-27編寫程序,拆分Excel文件工作表中所有合并的區(qū)域,把拆分得到的所有單元格內(nèi)的值都設(shè)置為拆分前單元格的值。

fromcopyimportdeepcopyimportopenpyxlfn=r'包含若干合并單元格區(qū)域.xlsx'wb=openpyxl.load_workbook(fn)ws=wb.worksheets[0]#拆分單元格時(shí)原始數(shù)據(jù)會(huì)變,導(dǎo)致有部分區(qū)域沒(méi)有拆分#所以使用深復(fù)制,在原始數(shù)據(jù)上進(jìn)行遍歷和操作forareaindeepcopy(ws.merged_cells):ws.unmerge_cells(start_row=area.min_row,end_row=area.max_row,start_column=area.min_col,end_column=area.max_col)value=ws.cell(area.min_row,area.min_col).value#把拆分得到的所有單元格內(nèi)文本都設(shè)置為拆分前單元格內(nèi)的值forrowinrange(area.min_row,area.max_row+1):forcolinrange(area.min_col,area.max_col+1):ws.cell(row=row,column=col,value=value)wb.save('拆分單元格結(jié)果.xlsx')8.3.3Excel文件操作例8-28編寫程序,提取xlsx文件中的所有圖片。fromzipfileimportZipFilefromos.pathimportbasenamedefextract_images(xlsx_fn):withZipFile(xlsx_fn)aszf:foriteminzf.filelist:fn=item.filenameiffn.endswith(('.jpg','.jpeg','.png','.bmp')):print(fn)withopen(basename(fn),'wb')asfp:fp.write(zf.read(fn))extract_images('包含圖片的文件.xlsx')8.3.3Excel文件操作例8-29編寫程序,把Excel文件中多個(gè)工作表導(dǎo)入為Word文件中多個(gè)表格,并實(shí)現(xiàn)相反操作。code\例8-29.py8.3.4PowerPoint文件操作例8-30編寫程序,讀取并輸出PowerPoint文件“帶表格的演示文稿.pptx”中所有表格的內(nèi)容。frompptximportPresentationfrompptx.enum.shapesimportMSO_SHAPE_TYPEobj=Presentation('帶表格的演示文稿.pptx')forindex,slideinenumerate(obj.slides,start=1):print(f'========\n幻燈片{index}')table_num=0forshapeinslide.shapes:ifshape.shape_type==MSO_SHAPE_TYPE.TABLE:table_num=table_num+1print(f'\n第{table_num}個(gè)表格')forrowinshape.table.rows:forcellinrow.cells:print(cell.text_frame.text,end='')print()8.3.4PowerPoint文件操作例8-31編寫程序,批量提取pptx文件中所有幻燈片的標(biāo)題和備注文本。frompptximportPresentationfn=r'帶備注的演示文稿.pptx'obj=Presentation(fn)forindex,slideinenumerate(obj.slides,start=1):print(f'第{index}頁(yè)幻燈片'.center(20,'='))#PowerPoint自帶模板中每頁(yè)幻燈片頂部的文本為title#如果自定義模板中沒(méi)有title,返回空值Nonetitle=slide.shapes.titleiftitle:print('標(biāo)題文本:\n',title.text)else:print('這一頁(yè)幻燈片沒(méi)有標(biāo)題')ifslide.has_notes_slide:#如果有備注就輸出其中的文本print('備注文本:\n',slide.notes_slide.notes_text_frame.text)else:print('這一頁(yè)幻燈片沒(méi)有備注')8.3.4PowerPoint文件操作例8-32編寫程序,搜索并輸出當(dāng)前文件夾中包含特定關(guān)鍵字字符串的Word、Excel、PowerPoint文件名。code\例8-32.py程序的兩種使用方式如下所示,第一種方式只搜索當(dāng)前文件夾中包含字符串“董付國(guó)”的Office文檔,第二種方式會(huì)搜索當(dāng)前文件夾及其所有文件夾中包含字符串“董付國(guó)”的Office文檔。Python.exe

例8-32.py

董付國(guó)Python.exe

例8-32.py

/s董付國(guó)8.3.5PDF文件操作例8-33安裝擴(kuò)展庫(kù)pymupdf,然后編寫程序處理PDF文件,完成提取文本、合并PDF文檔、按頁(yè)拆分成獨(dú)立圖片、合并圖片為PDF文件、提取PDF中的圖片以及添加注釋、高亮、下畫線、刪除線等任務(wù)。code\例8-33.py8.3.5PDF文件操作例8-34安裝擴(kuò)展庫(kù)PyPDF2,然后編寫程序,提取給定PDF文件中任意頁(yè)面,對(duì)其進(jìn)行自由拆分。fromPyPDF2importPdfFileReader,PdfFileWriterdefsplit_pdf(filename,result,start=0,end=None):'''從filename中提取[start,end)之間的頁(yè)碼內(nèi)容保存為result'''#打開原始pdf文件pdf_src=PdfFileReader(filename)ifendisNone:#獲取總頁(yè)數(shù)end=pdf_src.getNumPages()withopen(result,'wb')asfp:#創(chuàng)建空白pdf文件pdf=PdfFileWriter()#提取頁(yè)面內(nèi)容,寫入空白文件fornuminrange(start,end):pdf.addPage(pdf_src.getPage(num))#寫入結(jié)果pdf文件pdf.write(fp)fn=r'測(cè)試文件.pdf'split_pdf(fn,'1.pdf',0,3)split_pdf(fn,'2.pdf',1,3)split_pdf(fn,'3.pdf',2,3)8.3.5PDF文件操作例8-35安裝擴(kuò)展庫(kù)pdfplumber,然后編寫程序,提取PDF文件中的表格保存為Excel文件。importpdfplumberfromopenpyxlimportWorkbookdefextract_table(pdf_file):wb=Workbook()wb.remove(wb.worksheets[0])withpdfplumber.open(pdf_file)aspdf:index=0forpageinpdf.pages:tables=page.extract_tables()fortableintables:ws=wb.create_sheet(title=f'Sheet{index}')forrowintable:ws.append(row)index=index+1wb.save('提取結(jié)果.xlsx')extract_table(

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論