第8章 基于文件和设备的数据采集_第1页
第8章 基于文件和设备的数据采集_第2页
第8章 基于文件和设备的数据采集_第3页
第8章 基于文件和设备的数据采集_第4页
第8章 基于文件和设备的数据采集_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章基于文件和设备的数据采集董付国微信公众号:Python小屋本章学习目标了解文件的概念与常见文件类型的扩展名理解文本文件与二进制文件的概念与区别熟练掌握内置函数open()的用法理解并熟练应用内置函数open()的mode参数与encoding参数熟练掌握从文本文件中读取数据的方法熟练掌握上下文管理语句with的用法熟练掌握os、os.path、shutil模块的使用熟练掌握从Word、Excel、PowerPoint、PDF等类型文件中读取数据的方法了解从图像、视频、音频等类型文件中采集数据的相关技术了解从麦克风、摄像头、温度/湿度传感器等设备中采集数据的相关技术8.1文本文件与二进制文件内容操作文件是长久保存信息并支持重复使用和反复修改的重要方式,同时也是信息交换的重要途径之一。记事本文件、日志文件、各种配置文件、数据库文件、图形图像文件、音频视频文件、可执行文件、Office文档、动态链接库文件等等,都以不同的形式存储在各种存储设备(如硬盘、U盘、光盘、云盘、网盘等等)上。8.1文本文件与二进制文件内容操作按内容读写方式的不同,可以把文件分为文本文件和二进制文件两大类。(1)文本文件文本文件可以使用记事本、Notepad++、vim、gedit、ultraedit、Emacs、SublimeText3、IDLE或类似软件自动识别编码格式并直接进行显示和编辑,人类能够直接阅读和理解。文本文件由若干文本行组成,每行以换行符结束,文件中包含英文字母、汉字、数字字符、标点符号等。扩展名为txt、log、ini、c、cpp、h、py、pyw、html、js、css、csv、json的文件都属于文本文件。(2)二进制文件数据库文件、图形图像文件、可执行文件、动态链接库文件、音频文件、视频文件、Office文档等均属于二进制文件。二进制文件无法用记事本或其他普通字处理软件正常进行显示和编辑,人类也无法直接阅读和理解,需要使用正确的软件进行解码或反序列化之后才能正确地读取、显示、修改或执行。二进制文件的扩展名非常多,例如docx、xlsx、pptx、dat、exe、dll、pyd、so、mp4、bmp、png、jpg、rm、rmvb、avi、db、sqlite、mp3、wav、ogg、m4a。8.1.1内置函数open()Python内置函数open()使用指定的模式和编码格式打开指定文件,完整语法为:open(file,mode='r',buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)主要参数含义如下:参数file指定要操作的文件名称,如果该文件不在当前文件夹或子文件夹中,建议使用绝对路径,确保从当前工作文件夹出发可以访问到该文件。为了减少路径中分隔符“\”的输入,可以使用原始字符串。参数mode指定打开文件后的处理方式,或者说打开文件以后要做什么。参数buffering指定缓存模式,-1表示由操作系统自动维护缓存,0表示不使用缓存(仅适用于二进制模式),1表示行缓存模式(仅适用于文本模式),大于1的整数表示设置缓存大小。参数encoding指定对文本进行编码和解码的方式,只适用于文本模式。默认值None表示依赖于具体的操作系统,在Windows操作系统中默认使用UTF-8编码格式。8.1.1内置函数open()如果执行成功,open()函数返回1个文件对象,然后通过这个文件对象的方法可以对文件进行读写操作,最后调用文件对象的close()方法关闭文件。如果指定的文件路径不存在、访问权限不够、磁盘空间不够或其他原因导致创建文件对象失败则抛出IOError异常。对文件内容操作完以后,一定要关闭文件。然而,即使我们写了关闭文件的代码,也无法保证文件一定能够正常关闭。例如,如果在打开文件之后和关闭文件之前的代码发生错误导致程序崩溃,这时文件就无法正常关闭。在管理文件对象时推荐使用with关键字,可以避免这个问题。8.1.2文件对象常用方法方法功能说明close()把写缓冲区的内容写入文件,关闭文件read(size=-1,/)从以'r'、'r+'模式打开的文本文件中读取并返回最多size个字符,或从以'rb'、'rb+'模式打开的二进制文件中读取并返回最多size个字节,参数size的默认值-1表示读取文件中全部内容。每次读取时从文件指针当前位置开始读,读取完成后自动修改文件指针到读取结束的下一个位置readline(size=-1,/)参数size=-1时从以'r'、'r+'模式打开的文本文件中读取当前位置开始到下一个换行符(包含)之前的所有内容,如果当前已经到达文件尾就返回空字符串。如果参数size为正整数则读取当前位置开始到下一个换行符(包含)之间的最多size个字符,指定其他任意负整数时都与-1等价。每次读取时从文件指针当前位置开始读,读取完成后自动修改文件指针到读取结束的下一个位置readlines(hint=-1,/)参数hint=-1时从以'r'、'r+'模式打开的文本文件中读取所有内容,返回包含每行字符串的列表;参数hint为正整数时从当前位置开始读取若干连续完整的行,如果已读取的字符数量超过hint的值就停止读取seek(cookie,whence=0,/)定位文件指针,把文件指针移动到相对于whence的偏移量为cookie字节的位置。其中whence为0表示文件头,1表示当前位置,2表示文件尾。对于文本文件,whence=2时cookie必须为0;对于二进制文件,whence=2时cookie可以为负数。不论以文本模式还是二进制模式打开文件,都是以字节为单位进行定位write(text,/)把text的内容写入文件,如果写入文本文件则text应该是字符串,如果写入二进制文件则text应该是字节串。返回写入字符串或字节串的长度writelines(lines,/)把列表lines中的所有字符串写入文本文件,并不在lines中每个字符串后面自动增加换行符。如果确实想让lines中的每个字符串写入文本文件之后各占一行,应由程序员保证每个字符串都以换行符结束8.1.3上下文管理语句with在实际开发中,读写文件应优先考虑使用上下文管理语句with来管理文件对象,这会减少很多麻烦,代码也更加简洁。关键字with可以自动管理资源,不论因为什么原因跳出with块,总能保证资源被正确关闭。除了用于文件操作,with关键字还可以用于数据库连接、网络连接或类似场合。用于文件内容读写时,with语句的语法形式如下:withopen(filename,mode,encoding,...)asfp:#这里写通过文件对象fp读写文件内容的代码8.1.4文本文件操作例题解析例8-1已知文件“商场一楼手机信号强度.txt”中保存了某商场平面图部分位置的手机信号强度测量结果,每行表示一个测量位置的x、y坐标和信号强度,其中x、y坐标以商场西南角为坐标原点,向东为x正轴,向北为y正轴。文件内容格式如下,0,0,600,3,705,0,6810,0,73编写程序,读取该文件内容,输出信号最弱和最强的所有位置的坐标和信号强度。8.1.4文本文件操作例题解析fn='商场一楼手机信号强度.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('信号最弱的位置及强度:',*min_position,sep='\n')print('信号最强的位置及强度:',*max_position,sep='\n')8.1.4文本文件操作例题解析例8-2编写程序,读取并输出Python安装目录中文本文件news.txt的所有行内容。withopen('news.txt',encoding='utf8')asfp:forlineinfp:print(line)8.1.4文本文件操作例题解析例8-3编写程序,提取.ipynb格式文件中的Python代码并保存为.py格式的文件。importjsonwithopen('Pandas数据分析实战.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已知文件“手机用户通话记录.csv”中的内容格式如下,用户名,开始通话时间,通话时长(秒)user897,2020-07-0100:00:00,828user771,2020-07-0100:13:34,2677user928,2020-07-0100:17:12,1073编写程序,读取文件内容并统计指定时间段通话总时长最多的用户及通话总时长。8.1.4文本文件操作例题解析fromcsvimportreaderfromoperatorimportitemgetterdefmain(flag):#flag=0返回[上午8:00,下午18:00)之间打电话总时长最多的用户名#flag=1返回其他时间打电话总时长最多的用户名data={}withopen('手机用户通话记录.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]#总时长data[user]=data.get(user,0)+int(row[2])#升序排序,最后一个returnsorted(data.items(),key=itemgetter(1))[-1]print(main(0))print(main(1))8.2文件级与文件夹级操作os模块常用函数函数功能说明chdir(path)把path设为当前工作文件夹getcwd()返回表示当前工作文件夹的字符串getcwdb()放回表示当前工作文件夹的字节串listdir(path=None)返回path文件夹中的文件和子文件夹名字组成的列表,path默认值None表示当前文件夹mkdir(path,mode=511,*,dir_fd=None)创建文件夹,在Windows平台上mode参数无效rmdir(path,*,dir_fd=None)删除path指定的文件夹,要求其中不能有文件或子文件夹remove(path,*,dir_fd=None)删除指定的文件,要求用户拥有删除文件的权限,并且文件没有只读或其他特殊属性rename(src,dst,*,src_dir_fd=None,dst_dir_fd=None)重命名文件或文件夹startfile(filepath[,operation])使用关联的应用程序打开指定文件或启动指定应用程序,如果参数filepath指定的是URL,会自动使用默认浏览器打开这个地址stat(path,*,dir_fd=None,follow_symlinks=True)查看文件的属性,包括创建时间、最后访问时间、最后修改时间、大小等等8.2文件级与文件夹级操作os.path模块常用函数函数功能说明abspath(path)返回给定路径的绝对路径basename(p)返回指定路径的最后一个路径分隔符后面的部分,例如basename(r'C:\Python310\python.exe')的值为'python.exe'dirname(p)返回给定路径的最后一个路径分隔符前面的部分,例如dirname(r'C:\Python310\python.exe')的值为'C:\\Python310'exists(path)判断指定的路径是否存在,返回True或Falsegetatime(filename)返回表示文件最后访问时间的纪元秒数(从格林尼治时间1970年1月1日0时0分0秒开始计算,经过的秒数)getctime(filename)返回表示文件创建时间(Windows)或元数据最后修改时间(Unix)的纪元秒数getmtime(filename)返回表示文件最后修改时间的纪元秒数getsize(filename)返回文件的大小,单位为字节isdir(s)判断指定的路径是否为文件夹,返回True或Falseisfile(path)判断指定的路径是否为文件,返回True或Falsejoin(path,*paths)连接两个或多个path,相邻路径之间插入路径分隔符,返回连接后的字符串8.2文件级与文件夹级操作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=',')运行结果为:1659362398.0,1660547290.5947957,1659362398.02022-08-0121:59:58,2022-08-1515:08:10,2022-08-0121:59:588.2文件级与文件夹级操作例8-5编写程序,按照深度优先的顺序递归遍历并输出指定文件夹的目录树结构,包括所有文件及其所有子文件夹中的文件名。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文件级与文件夹级操作例8-6编写程序,按照广度优先的顺序遍历并输出指定文件夹的目录树结构,包括所有文件及其所有子文件夹中的文件名。fromosimportlistdir,getcwdfromos.pathimportjoin,isdirdeflistDirWidthFirst(directory):dirs=[directory]#如果还有没遍历过的文件夹,继续循环whiledirs:#遍历需要遍历但还没遍历过的第一项current=dirs.pop(0)#遍历该文件夹,如果是文件就直接输出显示#如果是文件夹,输出显示后,追加到列表尾部表示这是需要遍历的文件夹forsubPathinlistdir(current):path=join(current,subPath)print(path)ifisdir(path):#记下这个文件夹,后面再处理其中的文件和子文件夹dirs.append(path)listDirWidthFirst(getcwd())8.3Word、Excel、PowerPoint、PDF文件内容读取

8.3.1docx、xlsx、pptx文件操作基础扩展库python-docx、docx2python等提供了docx格式Word文档操作的接口。扩展库python-docx可以使用pipinstallpython-docx命令进行安装,安装之后叫docx。扩展库docx2python的安装名称和使用名称是一致的。在docx文件中,有很多sections(节)、paragraphs(段落)、tables(表格)、inline_shapes(行内元素)组成,其中每个段落又包括一个或多个run(一段连续的具有相同样式的文本),每个表格又包含一个或多个rows(行)和columns(列),每行或列又包括多个cells(单元格)。所有这些对象都具有大量的属性,通过这些属性来读取或控制Word文档中的内容和格式。8.3.1docx、xlsx、pptx文件操作基础Python扩展库openpyxl提供了操作xlsx格式Excel文件的接口,可以使用pipinstallopenpyxl安装。每个Excel文件称为一个workbook(工作簿),由若干worksheet(工作表)组成,每个工作表又由若干rows(行)和columns(列)组成,每个行和列由若干单元格组成。在单元格中可以存储整数、实数、字符串、公式、图表等对象。8.3.1docx、xlsx、pptx文件操作基础Python扩展库python-pptx提供了pptx格式PowerPoint文件操作的接口,可以使用pipinstallpython-pptx命令安装,安装之后的名字叫pptx。每个PowerPoint文件称为一个Presentation(演示文档),每个Presentation对象包含一个由所有幻灯片组成的属性slides,每个幻灯片对象的属性Shapes包含了这一页幻灯片上的所有元素,可以是TEXT_BOX(文本框)、PICTURE(图片)、CHART(图表)、TABLE(表格)或其他等元素,分别对应不同的shape_type属性值。8.3.2Word文件操作例8-7编写程序,检查word文档的连续重复字,例如“用户的的资料”或“需要需要用户输入”之类的情况。fromdocximportDocumentdoc=Document('董付国《Python网络程序设计》.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格式的教材电子版中例题、插图和表格清单。本例代码中使用到了正则表达式模块re,其中的函数match()用来检查目标字符串是否匹配特定的模式,在正则表达式中'\d'可以匹配单个任意阿拉伯数字字符,'\d+'用来匹配一个或任意多个连续的阿拉伯数字字符。8.3.2Word文件操作importrefromdocximportDocumentresult={'li':[],'fig':[],'tab':[]}doc=Document(r'董付国《Python程序设计与数据采集》.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():#输出结果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文档中所有嵌入式图片和浮动图片。使用python-docx扩展库提取图片比较繁琐,可以安装和使用另一个扩展库docx2python来完成这个任务。fromdocx2pythonimportdocx2pythonobj=docx2python('包含图片的文档.docx')forname,imageDatainobj.images.items():withopen(name,'wb')asfp:fp.write(imageData)8.3.2Word文件操作例8-11编写程序,提取docx文档所有超链接文本和地址。代码一(适用于WPS创建的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创建的docx格式文档):fromreimportfindallfromzipfileimportZipFilewithZipFile('带超链接的文档(Word版).docx')aszf:#提取资源IDcontent=zf.read('word/document.xml').decode()#这个正则表达式中有2个模式,模式0是整个正则表达式,模式1是IDpattern=r'(<w:hyperlink.+?r:id="(.+?)".+?</w:hyperlink>)'#findall()只返回圆括号里的内容pairs=findall(pattern,content)content=zf.read('word/_rels/document.xml.rels').decode()forpairinpairs:#根据ID提取对应的超链接地址pattern=f'<RelationshipId="{pair[1]}".*?Target="(.+?)"'target=findall(pattern,content)[0]#超链接文本可能在多个run中,连接到一起pattern='<w:t>(.+?)</w:t>'txt=''.join(findall(pattern,pair[0]))print(txt,target,sep=':')8.3.2Word文件操作例8-12编写程序,读取并输出docx文档中所有标题。fromdocximportDocumentobj=Document('包含标题的文档.docx')forpinobj.paragraphs:style_name=ifstyle_name.startswith('Heading'):print(style_name,p.text,sep=':')8.3.2Word文件操作例8-13编写程序,读取并输出docx文档中文本框里的文本。fromdocximportDocumentfilename=r'带文本框的测试文件.docx'document=Document(filename)#遍历文档每个子节点forchildindocument.element.body.iter():#只处理textboxifchild.tag.endswith('textbox'):print(f'\n{"="*20}',end='')#遍历文本框中每个子节点forcinchild.iter():c_tag=c.tag#遇到段落,换行ifc_tag.endswith('main}pPr'):print()#遇到段内run,提取并输出文本elifc_tag.endswith('main}r'):print(c.text,end='')8.3.2Word文件操作例8-14编写程序,读取并输出docx文档中的所有批注。fromreimportfindallfromzipfileimportZipFilefn=r'带批注的测试文件.docx'withZipFile(fn)asfp:try:content=fp.read('word/comments.xml').decode('utf8')except:content=''ifnotcontent:print('这个文档没有批注')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)#把脚注的内容复制到剪贴板r.Copy()#获取剪贴板中的内容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('我是一个莫得脚注的文档.docx')8.3.2Word文件操作例8-17编写程序,统计docx文档中除黑色之外使用最多的前3种文本颜色。fromoperatorimportitemgetterfromdocximportDocumentfromdocx.sharedimportRGBColordefmain(fn):word=Document(fn)colors={}#遍历所有段落forpinword.paragraphs:#遍历所有runforrinp.runs:#当前run的文本颜色color=r.font.color.rgb#如果没有显式设置字体颜色,则为Noneifcolornotin(RGBColor(0,0,0),None):colors[color]=colors.get(color,0)+1#按颜色使用次数降序排序colors=sorted(colors.items(),key=itemgetter(1),reverse=True)#返回元组,包含前3种使用次数最多的十六进制颜色returntuple(map(str,map(itemgetter(0),colors[:3])))print(main('不同颜色的文本.docx'))8.3.3Excel文件操作例8-18编写程序,读取“学生多次考试成绩.xlsx”文件中学生多次参加不同课程的考试数据,统计每个学生每门课程的最高成绩,统计结果写入新文件“学生每门课程最高分.xlsx”。代码一(使用扩展库openpyxl):code\例8-18_1.py8.3.3Excel文件操作代码二(使用扩展库Pandas):importpandasaspddefgetResult(oldfile,newfile):df=pd.read_excel(oldfile)df.groupby(['姓名','课程']).max().to_excel(newfile)oldfile=r'学生多次考试成绩.xlsx'newfile=r'学生每门课程最高分.xlsx'getResult(oldfile,newfile)8.3.3Excel文件操作例8-19文件“电影导演和演员.xlsx”中有三列分别为电影名称、导演和演员列表(同一个电影可能会有多个演员,每个演员姓名之间使用中文全角逗号分隔),如图8-4所示。编写程序统计每个演员的参演电影分别有哪些、最受欢迎(参演电影数量最多)的演员名称以及关系最好(共同参演电影数量最多)的两个演员。8.3.3Excel文件操作fromitertoolsimportcombinationsfromopenpyxlimportload_workbookdefget_actors(filename):result=dict()#打开xlsx文件,获取第一个worksheetws=load_workbook(filename).worksheets[0]#遍历Excel文件中的所有行forindex,rowinenumerate(ws.rows):#跳过第一行的表头ifindex==0:continue#获取电影名称和演员列表filmName,actor=row[0].value,row[2].value.split(',')#遍历该电影的所有演员,统计参演电影forainactor:#每个元素的“键”为演员名称,“值”为参演电影名称的集合result[a]=result.get(a,set())|{filmName}returnresult8.3.3Excel文件操作data=get_actors('电影导演和演员.xlsx')#按演员名称编号升序排序,方便查看输出结果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,()]#选择法,查找共同参演电影数量最多的两个演员foractor1,actor2incombinations(actors,2):common=len(data[actor1]&data[actor2])ifcommon>trueLove[0]:trueLove=[common,(actor1,actor2)]return('关系最好的两个演员是{0[1]},''Ta们共同主演的电影数量是{0[0]}'.format(trueLove))print(relations())8.3.3Excel文件操作例8-20编写程序,输出Excel文件中单元格中公式计算结果。假设Excel文件中第2个工作表中第4列为公式。importopenpyxl#打开Excel文件,参数data_only=True是关键wb=openpyxl.load_workbook('data.xlsx',data_only=True)#获取WorkSheet,实际使用时根据情况设置下标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安装扩展库xlwings,然后编写程序,批量提取Excel文件中文本框组件中的文本。importxlwingsasxwdefprint_textbox(xlsx_file):#先创建App对象,在App对象中打开xlsx文件,最后退出App对象#如果使用xlwings.Book直接打开xlsx文件,close()之后会留下一个空的Excel进程#后台打开xlsx文件,不自动添加空白表格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文件中人员信息并根据身份证号查找超过40岁的人。code\例8-23.py8.3.3Excel文件操作例8-24文件“超市营业额.xlsx”中保存了某超市2019年3月1日至5日各员工在不同时段、不同柜台的销售额。部分数据如图8-6所示。编写程序,读取该文件中的数据,统计每个员工的销售总额、每个时段的销售总额、每个柜台的销售总额。8.3.3Excel文件操作代码一(使用扩展库openpyxl):fromopenpyxlimportload_workbook#3个字典分别存储按员工、按时段、按柜台的销售总额persons=dict()periods=dict()goods=dict()ws=load_workbook('超市营业额.xlsx').worksheets[0]forindex,rowinenumerate(ws.rows):#跳过第一行的表头ifindex==0:continue#获取每行的相关信息,下画线表示匿名变量,接收但不存储值,用来占位_,name,_,time,num,good=map(lambdacell:cell.value,row)#根据每行的值更新三个字典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文件操作代码二(使用扩展库Pandas):importpandasaspd#设置每列对齐pd.set_option('display.unicode.ambiguous_as_wide',True)pd.set_option('display.unicode.east_asian_width',True)df=pd.read_excel('超市营业额.xlsx')print(df.groupby('姓名').sum().drop(['工号','日期'],axis=1),end='\n\n')print(df.groupby('时段').sum().drop(['工号','日期'],axis=1),end='\n\n')print(df.groupby('柜台').sum().drop(['工号','日期'],axis=1),end='\n\n')8.3.3Excel文件操作例8-25编写程序,读取Excel文件中的个人爱好,在最后插入一列,对每个人的爱好进行汇总。8.3.3Excel文件操作fromopenpyxlimportload_workbookwb=load_workbook('每个人的爱好.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='所有爱好')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('每个人的爱好汇总.xlsx')8.3.3Excel文件操作例8-26编写程序,随机化Excel文件中的学号和姓名,进行数据脱敏。fromrandomimportchoicesfromstringimportascii_letters,digitsfromopenpyxlimportload_workbookwb=load_workbook(r'演示用数据.xlsx')ws=wb.worksheets[0]last_student=Noneforindex,rowinenumerate(ws.rows,start=1):ifindex==1:continuecurrent_student=[row[0].value,row[1].value]#假设每个学生的信息是连续存放在一起的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'脱敏结果.xlsx')8.3.3Excel文件操作例8-27编写程序,拆分Excel文件工作表中所有合并的区域,把拆分得到的所有单元格内的值都设置为拆分前单元格的值。

fromcopyimportdeepcopyimportopenpyxlfn=r'包含若干合并单元格区域.xlsx'wb=openpyxl.load_workbook(fn)ws=wb.worksheets[0]#拆分单元格时原始数据会变,导致有部分区域没有拆分#所以使用深复制,在原始数据上进行遍历和操作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#把拆分得到的所有单元格内文本都设置为拆分前单元格内的值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('拆分单元格结果.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文件中多个工作表导入为Word文件中多个表格,并实现相反操作。code\例8-29.py8.3.4PowerPoint文件操作例8-30编写程序,读取并输出PowerPoint文件“带表格的演示文稿.pptx”中所有表格的内容。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}个表格')forrowinshape.table.rows:forcellinrow.cells:print(cell.text_frame.text,end='')print()8.3.4PowerPoint文件操作例8-31编写程序,批量提取pptx文件中所有幻灯片的标题和备注文本。frompptximportPresentationfn=r'带备注的演示文稿.pptx'obj=Presentation(fn)forindex,slideinenumerate(obj.slides,start=1):print(f'第{index}页幻灯片'.center(20,'='))#PowerPoint自带模板中每页幻灯片顶部的文本为title#如果自定义模板中没有title,返回空值Nonetitle=slide.shapes.titleiftitle:print('标题文本:\n',title.text)else:print('这一页幻灯片没有标题')ifslide.has_notes_slide:#如果有备注就输出其中的文本print('备注文本:\n',slide.notes_slide.notes_text_frame.text)else:print('这一页幻灯片没有备注')8.3.4PowerPoint文件操作例8-32编写程序,搜索并输出当前文件夹中包含特定关键字字符串的Word、Excel、PowerPoint文件名。code\例8-32.py程序的两种使用方式如下所示,第一种方式只搜索当前文件夹中包含字符串“董付国”的Office文档,第二种方式会搜索当前文件夹及其所有文件夹中包含字符串“董付国”的Office文档。Python.exe

例8-32.py

董付国Python.exe

例8-32.py

/s董付国8.3.5PDF文件操作例8-33安装扩展库pymupdf,然后编写程序处理PDF文件,完成提取文本、合并PDF文档、按页拆分成独立图片、合并图片为PDF文件、提取PDF中的图片以及添加注释、高亮、下画线、删除线等任务。code\例8-33.py8.3.5PDF文件操作例8-34安装扩展库PyPDF2,然后编写程序,提取给定PDF文件中任意页面,对其进行自由拆分。fromPyPDF2importPdfFileReader,PdfFileWriterdefsplit_pdf(filename,result,start=0,end=None):'''从filename中提取[start,end)之间的页码内容保存为result'''#打开原始pdf文件pdf_src=PdfFileReader(filename)ifendisNone:#获取总页数end=pdf_src.getNumPages()withopen(result,'wb')asfp:#创建空白pdf文件pdf=PdfFileWriter()#提取页面内容,写入空白文件fornuminrange(start,end):pdf.addPage(pdf_src.getPage(num))#写入结果pdf文件pdf.write(fp)fn=r'测试文件.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安装扩展库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('提取结果.xlsx')extract_table(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论