Python与Excel——Xlwings实战


比如说,我们在一个快递网站上爬取了几个快递的轨迹信息,我们需要将数据保存下来,一个常规做法是把数据保存在数据库里(Mysql,MongoDB,Redis),另一个是用Excel的形式存下来。对于非程序员来说,后者更加普遍,毕竟Excel是世界上使用最广泛的数据分析工具(不吹不黑)。

这次我们用xlwings来实现:

  1. 保存数据

  2. 更新数据

假设我们爬取到了快递信息,并且已经处理成了二维列表的形式以便处理(非本文重点不细说):

1.保存数据

import xlwings as xwwb = xw.Book()sht = wb.sheets[0] info_list = [['20190001','已揽收','凯撒邮局'], ['20190001','已发货','凯撒邮局'], ['20192288','已揽收','麻花镇邮局'], ['20192288','已发货','麻花镇邮局'], ['20192288','正在派送','阿里山']] 

首先,写入表头,

titles = [['包裹号','状态','地点']]sht.range('a1').value = titles 

然后写入轨迹信息

sht.range('a2').value = info_list 

保存

wb.save('Track.xlsx') 

这样,第一步保存数据就完成了

 
image

2.更新数据

我们第二天又爬取了一次信息,发现信息更新了:

[

['20190001','已揽收','凯撒邮局'],

['20190001','已发货','凯撒邮局'],

['20190001','正在派送','王村村口'],

['20190001','已签收','老王家'],

['20192288','已揽收','麻花镇邮局'],

['20192288','已发货','麻花镇邮局'],

['20192288','正在派送','阿里山'],

['20192288','已发货','小马家']

]

更新数据其实没什么难度,直接覆盖写入就好了

但是如果我想知道更新了多少条记录怎么办呢?

将数据去重,剩下的就是更新的

首先读取之前写入的信息:

import xlwings as xwwb = xw.Book('Track.xlsx')sht = wb.sheets[0]first = sht.range('a2').expand('table').valueprint(first) 

结果如下

 
image

乍一看没什么问题,仔细一看,包裹号都成了浮点数!写入的时候是字符串,读取出来就成了浮点数,所以这时候去重,由于数据类型不一致,无法真正去重。

思路一:直接转化数据类型,将每个列表的第一个元素转为整数,再转为字符串

for i in first: i[0] = str(round(i[0])) first_str.append(i)print(first_str) 
 
image

思路二:如果大家对Excel熟悉的话,就会知道,在数字前面加一个英文字符的单引号('),数字就变成文本格式了,所以我们可以在写入信息的时候加上一个单引号,这样Excel就不会乱改格式了。(以后可能会写一些Excel方面的东西)

import xlwings as xwwb = xw.Book('Track.xlsx')sht = wb.sheets[0]info_list = [["'20190001","已揽收","凯撒邮局"],["'20190001","已发货","凯撒邮局"],["'20192288","已揽收","麻花镇邮局"],["'20192288","已发货","麻花镇邮局"],["'20192288","正在派送","阿里山"]]sht.range('a2').value = info_listvalues = sht.range('a2').expand('table').valueprint(values) 
 
image

然后开始真正的去重

extra = [i for i in second if i not in first_str]print(extra)print(len(extra)) 

结果没问题,多出三个轨迹信息

 
image

为了介绍xlwings的插入功能,我们再来设想这样一种情况:

已经有了两个包裹的轨迹情况

 
image

但是我们得到了20190001包裹的最新情况,需要更新这一个包裹的信息:

[

["20190001","已揽收","凯撒邮局"],

["20190001","已发货","凯撒邮局"],

["20190001","正在派送","王村村口"],

["20190001","已签收","老王家"]

]

首先,去重

extra = [i for i in second if i not in first_str]print(extra) 

显示要更新的就一条

 
image

读取第一列的包裹号

rng = sht.range('a1').expand('table')nrows = rng.rows.countrow_a = sht.range(f'a1:a{nrows}').value 

找到要更新的包裹号

for i in extra: pkg = i[0] position = row_a.index(pkg) print(position) times = row_a.count(pkg) print(times) 
 
image

position = 1 是指在第二行出现,times = 3 是指一共有3个此包裹号的信息

所以要在第五行插入

rows = position+times+1sht.range(f'{rows}:{rows}').api.Insert() 
 
image

然后再写入更新的信息

sht.range(f'a{rows}').value = extra 

大功告成!保存

wb.save() 

其实折腾了半天都是为了这个插入语句

sht.range('单元格或行列').api.Insert() 
#插入列sht.range('a:a').api.Insert()#插入行sht.range('2:2').api.Insert()#插入单元格sht.range('b4').api.Insert() 

xlwings就说到这里了,讲得还算清楚吗?



作者:Python从放弃到真香
链接:https://www.jianshu.com/p/18b63172de6e
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM