2022泰迪杯数据分析 A题总结

该文介绍了使用Python和Bandizip工具对泰迪杯竞赛作品进行自动化处理,包括解压缩文件到特定文件夹,检查作品中特定文件的存在并计分,以及从PDF文件中提取图片并保存。同时,提供了不同方法将PDF中的图片转换为PNG格式。
摘要由CSDN通过智能技术生成

2022泰迪杯总结

1、基本处理

 任务1.1

将压缩文件“DataA.rar”中的所有作品解压到当前文件夹的同名 子文件夹(即以每份作品的作品号为子文件夹名)中。

import os

file_path = "DataA.rar"
command='Bandizip  x -y -o:./A题:竞赛作品的自动评判数据/ -target:name %s'%file_path
os.system(command)


path='./A题:竞赛作品的自动评判数据/DataA/'
for i in os.walk(path):
    for k in i[2]:
        file_path='./A题:竞赛作品的自动评判数据/DataA/%s'%k
        command='Bandizip  x -y  -o:./A题:竞赛作品的自动评判数据/DataA/  -target:name %s'%(file_path)
        os.system(command)
        os.remove(file_path)
        print(k+'  ok')

Bandizip.exe 参数:

Bandizip.exe <command> [<switches>...] <archive> [<files>...] [<path_to_extract>]

<command>指令

a添加档案到压缩包
x用完整路径选取档案
t测试档案的完整性
d从存档中删除文件
c创建新文件(用相同名称覆盖已有存档)
cd显示“新建档案”对话框
rn重命名存档中的档案
l列出文件(仅在bz.exe上可用)
/cmdfileRead command lines from specified file

<bcommand>批处理指令

bc“使用每个文件的名称压缩多个文件/文件夹。 如果现有存档具有相同的名称,则会创建(存档名称)(2)、(存档名称)(3)...。 如果未指定目标文件夹,则会在每个原始档案所在的文件夹中创建存档。 ”
bx“将多个存档文件选取到目标文件夹。 如果未指定目标文件夹,则会将文件解压缩到每个存档所在的文件夹。 ”
bt测试每个归档档案的完整性。

开关

-停止开关解析
-l:<0...9>设定压缩级别(0:存储、1:快速、5:默认值、9:最大)
-r-禁用递归子目录(默认)
-r启用递归子目录
-aoa无提示覆盖现有档案
-aos跳过并不覆盖现有档案
-aou自动重命名选中的文件 比如,name.txt→ name(2).txt
-sfx:"stub path"创建SFX存档并设定SFX存根的完整路径 (Bandizip c -sfx:“C:\Program Files\Bandizip\bdzsfx.x86.sfx” c:\out.exe c:\src.txt)
-zopfli使用Zopfil作为默认编码器(慢速)
-p:{password}配置存档的密码
-o:{dir}指定目的文件夹 仅适用于x命令和批处理命令(bc、bx、bt)
-storeroot:<yes|no>-storeroot:yes 将根目录存储为存档的顶级文件夹 -storeroot:no 不存储存文件的顶级文件夹
-y假设所有査询都是 如果未发生错误,则在任务完成时关闭(解)压缩窗口
-ex:{list}指定压缩时要排除的档案清单 -ex:hello.txt -ex:“.bak” -ex:“.bak; .tmp" -ex:.git
-root:{dir}压缩时在存档中指定根目录 (-root:top_folder)
-fmt:{fmt}指定存档格式 (zip, zipx, exe, tar, tgz, lzh, iso, 7z, gz, xz)
-v:{size}指定卷大小 (-v:1000000 -v:1440k -v:100MB ...)
-cmt:{comment}设定ZIP档案注释 (-cmt:Hello, -cmt:“Hello World!”)
-cmtfile:{filepath}指定用作ZIP文件注释的文字文件的路径 (-cmtfile:mycomment.txt, -cmtfile:“c:\test\my comment.txt”)
-t:NN指定压缩时使用的CPU线程数 (-t:10, -t:1, -t:0)
-cp:NN指定打开或选取文件时使用的内码表 (Bandizip x -cp:932 japanese.zip) 可用内码表的示例 - Chinese Simplified: 936 - Chinese Traditional: 950 - Japanese: 932 - Korean: 949 - UTF-8: 65001
-target:auto“使用此处选取智能解压缩功能将文件选取到目的文件夹。 如果未指定目的文件夹,则会将文件解压缩到每个存档所在的文件夹。 ”
-target:name“将文件解压缩到目标文件夹中的存档名称文件夹。 如果未指定目标文件夹,则会将文件选取到每个存档所在文件夹中的存档名称文件夹。 ”
-date将当前系统时间插入文件路径。 请参攷strftime语法。 ⁑ Bandizip.exe c -date f:\backup\%Y\%m\Backup%Y-%m-%d_%H-%M-%S.zip c:\source\

<switches> (仅限 Bandizip)

-email压缩且发送电子邮件
-target:dlg显示一个对话框,要求指定目标文件夹,并将文件解压缩到目标文件夹中的存档名称文件夹。 如果使用-o指定了任何文件夹,则该文件夹是对话框的默认文件夹。

<switches> (仅限bz.exe)

-list:v使用命令 l 时,显示文件的详细信息。
-list:s使用命令 l 时,仅显示文件名。
-consolemode:ansi以ANSI格式保存输出文字txt文件。
-consolemode:utf8以UTF-8格式保存输出文本txt文件。

任务1.2

在当前文件夹中新建“summary”子文件夹,在每份作品文件夹中 新建“image”子文件夹。

import os
​
path = r"./A题:竞赛作品的自动评判数据/DataA"
judgment_1 = os.path.exists(path + '/summary')  # 判断 summary 文件夹是否存在
if (judgment_1 == False):
    os.mkdir(path + '/summary')
​
listdir = os.listdir(path)
​
for dir in listdir:
    if  dir =="summary":
        pass
    else:
        judgment_2 = os.path.exists(path + f"/{dir}" + '/image')  # 判断 summary 文件夹是否存在
    if (judgment_2 == False):
        os.mkdir(path + f"/{dir}" + "/image")
listdir_dir = os.listdir(path + "/A101")
​

如果是读写文件的话,建议使用内置函数open()

如果是路径相关的操作,建议使用os的子模块os.path

如果要逐行读取多个文件,建议使用fileinput模块;

要创建临时文件或路径,建议使用tempfile模块;

要进行更高级的文件和路径操作则应当使用shutil模块。

os 常用操作做

os.name   #操作系统相关模块的名称

 """
 MAC  : posix,window 。
 """
 
os.envrion   #可以返回环境相关的信息,主要是各类环境变量
​
​
os.walk()   #这个函数需要传入一个路径作为top参数,函数的作用是在以top为根节点的目录树中游走,对树中的每个目录生成一个由(dirpath, dirnames, filenames)三项组成的三元组。
​
​
 os.listdir() # 列出(当前)目录下的全部路径(及文件)。该函数存在一个参数,用以指定要列出子目录的路径,默认为“.”,即“当前路径”。
​
​
os.mkdir()  #新建一个路径”。
​
os.remove()  #用于删除文件,如果指定路径是目录而非文件的话,就会抛出IsADirectoryError异常。删除目录应该使用os.rmdir()函数
​
os.rename() #该函数的作用是将文件或路径重命名,一般调用格式为os.rename(src, dst),即将src指向的文件或路径重命名为dst指定的名称
​
os.getcwd()  #获取当前工作路径”
​
os.chdir()  #切换当前工作路径为指定路径
​
os.path.exists()  #这个函数用于判断路径所指向的位置是否存在。若存在则返回True,不存在则返回False
​


任务1.3

判断每份作品中是否包含文件“task2_1.xlsx”“task2_2.xlsx” 2 “task2_3.pdf”及“task3.xlsx”,每包含一个文件得 2 分,满分 8 分。

import  os
​
path = r"./A题:竞赛作品的自动评判数据/DataA/"
​
data =[]
​
import pandas as pd
for i in os.walk(path):
    for j in i[1]:
        if j == "summary" or j =="image":
            pass
​
        else:
            listddd = os.listdir(path+j)
            count =0
​
            if "task2_1.xlsx" in listddd:
                count += 2
            if 'task2_2.xlsx' in listddd:
                count += 2
            if 'task2_3.pdf' in listddd:
                count += 2
            if 'task3.xlsx' in listddd:
                count += 2
            data.append([j, count])
​
​
data = pd.DataFrame(data)
print(data)
​
​
data.to_excel("./result/result1_3.xlsx",index=False)

任务1.4

 对每份作品提取文件“task2_3.pdf”中的图片,保存在“image” 文件夹的“XXXX_n.png”文件中,其中“XXXX”为作品号、n 为图片在文件 “task2_3.pdf”中的图片序号。提取所有作品中的图片信息,按照表 1 的格式保 存在文件夹“summary”的“result1_4.xlsx”文件中。将含有作品号 A118~A120 的结果截屏放在报告中。

import fitz
import re
import os

from  PIL import  Image
import math
import pandas as pd

def pdf2pic(path,pic_path,ISAN):

    #正则表达式查找图片

    checkXO = r"/Type(?= */XObject)"
    checkIM = r"/Subtype(?= */Image)"

    doc = fitz.open(path)
    # 图片计数
    imgcount = 0
    lenXREF =  doc.xref_length()

    # 打印PDF的信息
    print("文件名:{}, 页数: {}, 对象: {}".format(path, len(doc), lenXREF - 1))
    # 遍历每一个对象
    for i in range(1, lenXREF):
        # 定义对象字符串
        text = doc.xref_object(i)
        isXObject = re.search(checkXO, text)
        # 使用正则表达式查看是否是图片
        isImage = re.search(checkIM, text)
        # 如果不是对象也不是图片,则continue
        if not isXObject or not isImage:
            continue
        imgcount += 1
        # 根据索引生成图像
        pix = fitz.Pixmap(doc, i)
        # 根据pdf的路径生成图片的名称
        new_name = ISAN + "_{}.png".format(imgcount)
        new_name = new_name.replace(':', '')
        # 如果pix.n<5,可以直接存为PNG
        if pix.n < 5:
            pix.save(os.path.join(pic_path, new_name))
        # 否则先转换CMYK
        else:
            pix0 = fitz.Pixmap(fitz.csRGB, pix)
            pix0.save(os.path.join(pic_path, new_name))
            pix0 = None
        # 释放资源
        pix = None

path = "./A题:竞赛作品的自动评判数据/DataA/"

for i in os.walk(path):
    for k in i[1]:
        if k == 'summary' or k == 'image' :
            pass
        else:
            listddd = os.listdir(path+k)
            if 'task2_3.pdf' in listddd:
                pic_path=path+k+'/image'
                pdf2pic(path+k+'/task2_3.pdf', pic_path,k)
                print(k+' ok')
            else:
                pass


data2 = []

for i in os.walk(path):
    for k in i[1]:
        if k=='summary' or k=='image' :
            pass
        else:
            pic_path=path+k+'/image/'
            if not os.path.getsize(pic_path):
                data2.append([k,'无','无','无','无'])
            else:
                listddd=os.listdir(pic_path)
                for j in listddd:
                    if 'png' in j:
                        pic=pic_path+j
                        img = Image.open(pic)
                        data2.append([k,j.replace('.png',''),pic,str(img.size[0] )+'*'+str(img.size[1] ),str(math.ceil(os.path.getsize(pic)/1024))+'KB'])

df=pd.DataFrame(data2,columns=['作品号','图片编号','保存路径','图片分辨率','图片文件大小'])
print(df.head())
df.to_excel("./result/result1_4.xlsx",index=False)

Python提取PDF中图片的三种方式

1、pymupdf方式

import fitz   # pip install pymupdf
import re
import os
​
file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径
dir_path = r'C:\xxx' # 存放图片的文件夹
​
def pdf2image1(path, pic_path):
    checkIM = r"/Subtype(?= */Image)"
    pdf = fitz.open(path)
    lenXREF = pdf._getXrefLength()
    count = 1
    for i in range(1, lenXREF):
        text = pdf._getXrefString(i)
        isImage = re.search(checkIM, text)
        if not isImage:
            continue
        pix = fitz.Pixmap(pdf, i)
        new_name = f"img_{count}.png"
        pix.writePNG(os.path.join(pic_path, new_name))
        count += 1
        pix = None
​
pdf2image1(file_path, dir_path)

2、基于 pdf2image 库的两种方法

可以简单通过 pip install pdf2image 安装,但poppler才是真正起做用的转换器,因此需要额外安装和配置:

  • windows用户必须安装poppler for Windows,然后将bin/文件夹添加到PATH

  • Mac用户必须安装poppler for Mac

""""一"""
from pdf2image import convert_from_path,convert_from_bytes
import tempfile
from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError
import os
​
file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径
dir_path = r'C:\xxx' # 存放图片的文件夹
​
def pdf2image2(file_path, dir_path):
    images = convert_from_path(file_path, dpi=200)
    for image in images:
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        image.save(file_path + f'\img_{images.index(image)}.png', 'PNG')
​
pdf2image2(file_path, dir_path)



"""二"""


from pdf2image import convert_from_path,convert_from_bytes
import tempfile
from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError
import os
​
file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径
dir_path = r'C:\xxx' # 存放图片的文件夹
​
def pdf2image3(file_path, dir_path):
    images = convert_from_bytes(open(file_path, 'rb').read())
    for image in images:
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        image.save(file_path + f'\img_{images.index(image)}.png', 'PNG')
​
pdf2image3(file_path, dir_path)

核心方法covert_from_bytes包含大量参数。常用参数如下:

参数意义
pdf_pathPDF 文档路径
dpi图像质量(如果是学术期刊杂志常见 300dpi)
output_folder将生成的图像写入文件夹(而不是直接写入内存)
first_page起始转换页数
last_page转换至哪一页
fmt图像格式,可以指定为 png,默认为 ppm
thread_count允许参与转换的线程数
userpwPDF 的密码
output_file输出文件名
poppler_path指定 poppler 的安装路径,一开始配置好就无需指定

值得一提的是thread_count 参数,可以启动多线程会大大加快转换速度,尤其是 PDF 页面较多时。有兴趣的读者可以做尝试。

3、批量提取图片

pip install fitz 
pip install pymupdf
def save_pdf_img(path,save_path):
    '''
    path: pdf的路径
    save_path : 图片存储的路径
    '''
    # 使用正则表达式来查找图片
    checkXO = r"/Type(?= */XObject)" 
    checkIM = r"/Subtype(?= */Image)"  
    # 打开pdf
    doc = fitz.open(path)
    # 图片计数
    imgcount = 0
    # 获取对象数量长度
    lenXREF = doc.xref_length()
 
    # 打印PDF的信息
    print("文件名:{}, 页数: {}, 对象: {}".format(path, len(doc), lenXREF - 1))
    
    
    # 遍历每一个图片对象
    for i in range(1, lenXREF):
        # 定义对象字符串
        text = doc.xref_object(i)
#         print(i,text)
        isXObject = re.search(checkXO, text)
        # 使用正则表达式查看是否是图片
        isImage = re.search(checkIM, text)
        # 如果不是对象也不是图片,则continue
        if not isXObject or not isImage:
            continue
        imgcount += 1
        # 根据索引生成图像
        pix = fitz.Pixmap(doc, i)
        # 根据pdf的路径生成图片的名称
        new_name = path.replace('\\', '_') + "_img{}.png".format(imgcount)
        new_name = new_name.replace(':', '')
        # 如果pix.n<5,可以直接存为PNG
        if pix.n < 5:
            pix.writePNG(os.path.join(save_path, new_name))
        # 否则先转换CMYK
        else:
            pix0 = fitz.Pixmap(fitz.csRGB, pix)
            pix0.writePNG(os.path.join(save_path, new_name))
            pix0 = None
        # 释放资源
        pix = None
        print("提取了{}张图片".format(imgcount))
# pdf路径
path = r'/Users/wangwangyuqing/Desktop/data/img.pdf'
save_path = r'/Users/wangwangyuqing/Desktop/data'
save_pdf_img(path,save_path)

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕.晨风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值