网页表格抓取(Python中的表格分为图片型和文本型库)
优采云 发布时间: 2022-01-10 10:19网页表格抓取(Python中的表格分为图片型和文本型库)
内容
大家好,从PDF中提取信息是办公场景中经常用到的操作,也是读者经常在后台询问的操作。
如果内容不多,我们可以手动复制粘贴,但是如果需要批量提取,可以考虑使用Python。之前也转载了相关的文章,提到主要是使用pdfplumber库。今天我们再举一个例子。
通常,PDF中的表格分为图像类型和文本类型。文本类型分为简单型和复杂型。本文提供了这三个部分的示例。
使用的模块主要有
本文出现的PDF资料为从巨超信息官网下载的公开PDF文件。题目是关于财务管理的。相关发布信息及其他信息如下:
内容一共6页,后面会给出例子。
一、简单文本类型数据
简单的文本类型表格是指一个PDF页面中只有一个表格,表格的内容可以完全复制。比如我们选择的内容是PDF中的第四页,内容如下:
如您所见,此页面上只有一个表。接下来,我们将这张表写入Excel,先放代码。
import pdfplumber as pr
import pandas as pd
pdf = pr.open('关于使用自有资金购买银行理财产品的进展公告.PDF')
ps = pdf.pages
pg = ps[3]
tables = pg.extract_tables()
table = tables[0]
print(table)
df = pd.DataFrame(table[1:],columns = table[0])
for i in range(len(table)):
for j in range(len(table[i])):
table[i][j] = table[i][j].replace('\n','')
df1 = pd.DataFrame(table[1:],columns = table[0])
df1.to_excel('page2.xlsx')
得到的结果如下:
与PDF上的原创表格相比,内容完全相同。唯一不同的是,主要业务内容较多,展示不全面。现在让我们谈谈这段代码。
首先导入要使用的两个库。在pdfplumber中,open()函数用于打开PDF文件,代码使用相对路径。.open().pages是获取PDF的页数,打印ps值可以如下获取
pg = ps[3] 代表我们选择的第三页。
pg.extract_tables():可以输出页面中的所有表格,并返回一个结构层次为table→row→cell的嵌套列表。此时将页面上的整个表格放入一个大列表中,原创表格中的每一行形成大列表中的每个子列表。如果要输出单个外部列表元素,则得到的是由原创表的同一行中的元素组成的列表。
与此类似的是 pg.extract_table( ):返回多个独立的列表,其结构级别为 row→cell。如果页面中有多个行数相同的表,则默认输出最上面的表;否则,只输出行数最多的表。此时将表格的每一行作为一个单独的列表,列表中的每个元素都是原表格每个单元格的内容。
由于此页面中只有一个表格,因此我们需要表格集合中的第一个元素。打印表格值如下:
可以看出,上面有个不必要的字符\n,它的作用其实是换行但是我们在Excel中不需要它。所以需要去掉它,使用代码中的for循环和replace函数将控件替换为空格(即删除\n)。观察该表是一个收录 2 个元素的列表。
最后,df1 = pd.DataFrame(table[1:],columns = table[0])的作用就是创建一个数据框,把内容放到对应的行和列中。
此代码只是将数据保存到 Excel。如果需要进一步调整样式,可以使用openpyxl等模块进行修改。
二、复杂表提取
复杂表格是指表格样式不统一或一页有多个表格。以PDF的第五页为例:
可以看到这个页面有两个大表,仔细看其实有四个表。按照简单的表格类型提取方法,效果如下:
可以看到,所有的表格文本只是提取出来的,但实际上第一个表格被细分为两个表格,所以我们需要进一步修改,再次拆分这个表格!例如,将代码的上半部分提取如下:
import pdfplumber as pr
import pandas as pd
pdf = pr.open('关于使用自有资金购买银行理财产品的进展公告.PDF')
ps = pdf.pages
pg = ps[4]
tables = pg.extract_tables()
table = tables[0]
print(table)
df = pd.DataFrame(table[1:],columns = table[0])
for i in range(len(table)):
for j in range(len(table[i])):
table[i][j] = table[i][j].replace('\n','')
df1 = pd.DataFrame(table[1:],columns = table[0])
df2 = df1.iloc[2:,:]
df2 = df2.rename(columns = {"2019年12月31日":"2019年1-12月","2020年9月30日":"2020年1-9月"})
df2 = df2.loc[3:,:]
df1 = df1.loc[:1,:]
with pd.ExcelWriter('公司影响.xlsx') as i:
df1.to_excel(i,sheet_name='资产', index=False, header=True) #放入资产数据
df2.to_excel(i,sheet_name='营业',index=False, header=True) #放入营业数据
这段代码是在简单表格抽取的基础上修改的。第十四行代码的作用是提取另一个表头的信息,赋值给df2,然后重命名df2(使用rename函数)。)。
打印df2显示列名和第一行信息重复,所以我们需要重复刚才的步骤,使用loc()函数对数据框进行切割。
请注意,我们使用罕见的 pandas.Excelwriter 函数来覆盖 for 循环。这是为了避免直接写入导致最终数据覆盖原创数据。有兴趣的可以试试不带withopen的结果。最终结果如下:
如您所见,此表现在单独显示在两个工作表中。当然,也可以放在一张表中进行比较。
毕竟复杂形式的主观性很大,需要根据不同的情况进行不同的处理。写一个一劳永逸的方法更难!
三、图片表提取
最后也是最难处理的是图像类型的表单。人们经常问如何提取图像类型PDF中的表格/文本和其他信息。
其实本质上就是提取图片,如何进一步处理图片提取信息与Python提取PDF表格的话题关系不大!
这里我们也简单介绍一下,即先提取图片再进行OCR识别提取表格。Tesseract库可以在Python中使用,需要先安装pip。
pip install pytesseract
在 Python 中安装此库后,我们需要安装要在后面的代码中使用的 exe 文件。
http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe
只需下载并安装它。注意,如果按照正常步骤安装,是不会识别中文的,所以需要安装简体中文语言包。下载地址是,放在Tesseract-OCR的tessdata目录下。
接下来我们使用一个简单的图片类型pdf如下:
第一步是提取图片。这里使用GUI办公自动化系列中的图片提取软件对PDF中的图片进行提取,得到如下图片:
然后执行以下代码识别图片内容
import pytesseract
from PIL import Image
import pandas as pd
pytesseract.pytesseract.tesseract_cmd = 'C://Program Files (x86)/Tesseract-OCR/tesseract.exe'
tiqu = pytesseract.image_to_string(Image.open('图片型.jpg'))
print(tiqu)
tiqu = tiqu.split('\n')
while '' in tiqu: #不能使用for
tiqu.remove('')
first = tiqu[:6]
second = tiqu[6:12]
third = tiqu[12:]
df = pd.DataFrame()
df[first[0]] = first[1:]
df[second[0]] = second[1:]
df[third[0]] = third[1:]
#df.to_excel('图片型表格.xlsx') #转为xlsx文件
我们的想法是使用 Tesseract-OCR 解析图像,得到一个字符串,然后在字符串上使用 split 函数将字符串变成一个列表并删除 \n。
然后你可以发现我们的列表中还有空格。这时候,我们使用一个while循环来删除这些空字符。注意这里不能使用for循环,因为每次删除一个,列表中的元素都会前移一个,不会删除。完全地。最后就是使用pandas将这些转换成数据框形式。最终结果如下:
可以看到图片表格的内容被完美的解析处理了!当然,之所以能轻松搞定,也和这张表的简单性有关。真实场景中的图片可能会有更复杂的干扰因素,这就需要大家在处理的时候找到最合适的方法!
以上就是用Python提取PDF表格的方法的详细内容。更多关于Python提取PDF表格的内容,请关注脚本之家文章的其他相关话题!