excel抓取多页网页数据(干货速递|Python办公自动化之PDF的详细操作(全))
优采云 发布时间: 2022-01-09 15:11excel抓取多页网页数据(干货速递|Python办公自动化之PDF的详细操作(全))
大家好,我是小艺!
关注并star《小易学习笔记》,和小易一起学习数据分析!
点击关注|选星|干货
在日常的数据分析工作中,除了Excel数据的清洗,最常见的就是pdf、word、ppt等场景下的数据清洗。其实这还有一个更高的名字,叫做:办公自动化。
很多情况下,因为办公自动化场景中的数据是不规则的,首先要做的就是在数据分析之前把数据提取出来。
比如小艺的朋友“长河”在实际工作中遇到的真实问题:
虽然我对word的操作不是很熟悉,但也提供了自己的解决方案:
由于我擅长从PDF中提取数据,所以我也写过相关的操作文档:Python办公自动化中PDF的详细操作(全),所以如果原创数据是pdf,那我就按照我上面说的方法。操作
但是昌河已经自己做了pdf转换,所以问题就变成了多词的数据提取。
下面的文章是他在实现过程中的真实思考。有些数据比较敏感,文字已经编码,但不影响实际阅读和练习。
这也是实际工作中经常遇到的问题。希望大家下次能处理好。
以下为“昌河”投稿正文:
1. 问题的根源
我最近遇到的一个问题是从word中读取表格数据,然后整理成excel格式。
如下:
词形1,脱敏
如果表不多,只有几张表,手动处理也没问题,但是如果有140张表,9年的数据,怎么处理呢?
这时候,我们就需要一个程序来帮我们自动解决。
2.解决问题
确定问题后,我们接下来需要解决问题。
如果要从word中提取表格,常用的包是docx,为了规范提取中的数据,需要使用pandas
2.1 识别数据的行和列
如果要提取word表中的行列,需要了解表中有多少行列,然后根据具体的行列提取数据。
这部分内容可以参考B站的一些视频,使用Python操作Word
代码显示如下:
from docx import Document
doc = Document('one.docx')
tables = doc.tables
table = tables[0] # 表示读取的第一张表
# 查看一下多少行,多少列
print(len(table.rows),len(table.columns))
输出是:
5 14
可以看出我们提取的表信息是一个5行14列的数据。接下来,您需要考虑每一行和每一列的样子。
这里我们以第 5 行第 2 列为例进行说明:
继续写代码为:
print(table.cell(4,1).text)
输出是:
13905
270
5583
1528
1791
2315
2439
...
经过反复试验,我们终于知道我们需要的数据在哪里。
考虑到header过于复杂,难以定位,需要自己重写header信息。我们需要的是整个学校的数据,也就是下图中的部分。
提取表1对应的数据2.2 数据提取
接下来,执行数据提取:
list1 = [] # 定义一个空的列表存储数据
for row in range(4,len(table.rows)):
for column in range(len(table.columns)):
list1.append(table.cell(row,column).text)
print(len(list1))
print(list1)
提取的数据是一个很长的列表,输出为:
14
['--大学\--大学\--大学\---大学\n ----\n2186588\n203224\n146649\n329602\n214014\n299323\n47413\n71033']
接下来迭代转换为[[],[],[]]的形式
values = []
for i in list1:
i = i.split('\n')
values.append(i)
print(values)
结果处理完成,结果如下:
[['xx大学', 'xxxx大学', 'xx大学', ---'xxxx大学'],--- ['2186588', '203224', '146649', '329602', '214014', '299323', '47413', '71033']]
2.3 转换为DataFrame格式
之前已经对值进行了整理,然后可以重新整理表头信息:
colums = ['xx','xx','xx']
data_part1 = pd.DataFrame(values,columns).T
print(data_part1.head())
输出是:
学校名称 xxxxxx- ... xxxx xxxxxxx
0 XX大学 13905 ... 46526 2222470
1 XX大学 270 ... 0 67822
2 XX大学 5583 ... 331010 3557540
3 XX大学 1528 ... 12826 544980
4 XX大学 1791 ... 1270 844921
[5 rows x 14 columns]
考虑到一个word文件有两张表,第二张表的数据结构如下:
词形2,脱敏
第二张表的表头和第一张表的表头不同,处理方法相同,直接加代码即可:
table = tables[1]
for row in range(3, len(table.rows)):
for column in range(len(table.columns)):
table2.append(table.cell(row, column).text)
for h in table2:
h = h.split('\n')
values2.append(h)
data2 = pd.DataFrame(values2,column2).T
data = pd.concat([data1,data2],axis =1)
2.4 完整处理一个表
一个完整的字有两个表,所以需要用判断条件来处理,分为奇位表和偶位表。判断是根据某个数除以2时余数是否为0。
具体代码如下:
import pandas as pd
from docx import Document
column1 = ['xx','xx','xx','xx','xx']
column2 = ['xx','xx','xx','xx','xx']
for t in range(len(tables)):
if t % 2 == 0:
table1 = []
value1 = []
table = docx.tables[t]
for row in range(4, len(table.rows)):
for column in range(len(table.columns)):
table1.append(table.cell(row, column).text)
for j in table1:
j = j.split('\n')
value1.append(j)
data1 = pd.DataFrame(value1, column1).T
if t % 2 == 1:
table2 = []
value2 = []
table = docx.tables[t]
for row in range(3, len(table.rows)):
for column in range(len(table.columns)):
table2.append(table.cell(row, column).text)
for h in table2:
h = h.split('\n')
value2.append(h)
data2 = pd.DataFrame(value2,column2).T
data = pd.concat([data1,data2],axis =1)
2.5 完整处理多个表
如果是处理多张表,需要设置路径,然后在特定路径中处理
具体代码如下:
import pandas as pd
from docx import Document
import os
column1 = ['xx','xx','xx','xx','xx']
column2 = ['xx','xx','xx','xx','xx']
# 设置路径
path = os.listdir('E:\one-two')
# print(path)
for i in range(len(path)):
docx = Document('E:\one-two\{}'.format(path[i]))
# print('第{}表'.format(i+1),docx)
tables = docx.tables
for t in range(len(tables)):
if t % 2 == 0:
table1 = []
value1 = []
table = docx.tables[t]
for row in range(4, len(table.rows)):
for column in range(len(table.columns)):
table1.append(table.cell(row, column).text)
for j in table1:
j = j.split('\n')
value1.append(j)
data1 = pd.DataFrame(value1, column1).T
if t % 2 == 1:
table2 = []
value2 = []
table = docx.tables[t]
for row in range(3, len(table.rows)):
for column in range(len(table.columns)):
table2.append(table.cell(row, column).text)
for h in table2:
h = h.split('\n')
value2.append(h)
data2 = pd.DataFrame(value2,column2).T
data = pd.concat([data1,data2],axis =1)
print('正在保存{}'.format(i+1))
data.to_excel('E:\one-two\{}.xlsx'.format(i),index=False)
最终输出为:
最终结果3. 摘要
学习编程会带来很多问题和困惑。但这也是提高你的编程技能的关键。继续探索,看B站的视频,向大佬们求教,然后继续打印看看输出,你会得到你想要的!
感谢前辈提供的思路,补补补补!
一字一字的处理可以提高效率!
推荐历史文章:
一行Python代码去除照片背景
2021 年最有用的数据清理 Python 库
2021年Q3基金持仓数据分析,是满仓还是等风来?
历史上的今天,3步轻松重现!