Python 读取Excel(xlsx)文档中的链接
微信公众号导出的文章统计数据xlsx 文档结构如下。需要用到的数据第6行起,第1列是标题及链接,第3列是发表日期。
php方式解构excel文档已经做过了,最近都是拿python练手,顺便就试试在py中完成这个任务
下文无特别说明是python3.x代码,需要跳过弯路看正确解决方案的的直接跳到最后方案
尝试用 xlrd
能在python读excel文档的组件有很多。xlrd 是python官方的支持读取xls及xlsx格式,所以首选。
安装
pip install xlrd
读取xlsx文件代码
import xlrd
def readxlxs(file, sheet_index=0):
workbook = xlrd.open_workbook(file)
# 按索引读取工作表
sheet = workbook.sheet_by_index(sheet_index)
print("工作表名称:", sheet.name)
print("行数:", sheet.nrows)
print("列数:", sheet.ncols)
# 按工作表名称读取数据
# second_sheet = workbook.sheet_by_name("b")
# print("Second sheet Rows:", second_sheet.nrows)
# print("Second sheet Cols:", second_sheet.ncols)
# 获取单元格的数据
# cell_value = sheet.cell(1, 0).value
# print("获取第2行第1列的单元格数据:", cell_value)
data = []
for i in range(0, sheet.nrows):
data.append(sheet.row_values(i))
return data
xls = readxlxs("sample.xlsx")
for idx_row in range(5,len(xls)):
row = xls[idx_row]
print("date, title:", row[2], row[0])
这是从别人博客抄过来的,读取没有问题..emm好像缺少了什么,readxlsx()只返回单元格的内容 sheet.cell(r, o).value
不包含链接数据。
基于上文源码改进成以下版本
import xlrd
xls = xlrd.open_workbook("sample.xlsx", formatting_info=True)
sht = xls.sheet_by_index(0)
for row in range(5, sht.nrows):
rval = sht.row_values(row, start_colx=0, end_colx=2)
atitle = rval[0]
adate = rval[2]
alink = sht.hyperlink_map.get((row, 0))
url = None if link is None else link.url_or_path
print("date, title, link:", adate, atitle, url)
但是这个却报错NotImplementedError: formatting_info=True not yet implemented
搜索原因,被大神告知 open_workbook 方法打开第二参数 formatting_info 不支持 xlsx 格式,晴天霹雳。
xlrd cannot read the hyperlink without formatting_info, which is currently not supported for xlsx.
https://stackoverflow.com/questions/16676727/extracting-hyperlinks-from-excel-xlsx-with-python
被建议的解决办法是,把文档转换格式为 xls
word是旧转新,excel被要求新转旧,真的不安逸。
不妥协,放弃xlrd 继续看其他的解决办法
改尝试 openpyxl
安装
依然简单
pip install openpyxl
代码
import openpyxl
xls = openpyxl.load_workbook('sample.xlsx')
sht_names = xls.get_sheet_names() #获取所有sheet页名字
sht = xls.get_sheet_by_name(sht_names[0]) #第一页
for row in range(5, sht.max_row): #第五行开始是正文
atitle = sht.cell(row, 0).value
adate = sht.cell(row, 2).value
alink = sht.cell(row, 0).hyperlink.target
print("date, title, link:", adate, atitle, alink)
除了最大行数,读单元格值的方法名称略有改变外代码和上文xlrd的改动不大, 但是报错有两处需要注意ValueError: Row or column values must be at least 1
翻了一下文档,openpyxl 对行与列的定位下标从1开始算,与Office中的显示保持一致。
另外 sht.cell(row, col).hyperlink.target
这种方法也需要进行处理,当单元格不包含链接时
hyperlink 对象值为 None, 如果仍直接取 target的话会报错AttributeError: 'NoneType' object has no attribute 'target'
最后方案
依然使用 openpyxl ,对上一个代码的错误进行小修正
import openpyxl
xls = openpyxl.load_workbook('sample.xlsx')
sht_names = xls.get_sheet_names() #获取所有sheet页名字
sht = xls.get_sheet_by_name(sht_names[0]) #第一页
for row in range(6, sht.max_row+1): #第五行开始是正文
atitle = sht.cell(row, 1).value
adate = sht.cell(row, 3).value
alink = None if sht.cell(row, 1).hyperlink is None else sht.cell(row, 1).hyperlink.target
print("date, title, link:", adate, atitle, alink)
#尝试从一个没有链接的单元格取链接
noLinkObj = sht.cell(6, 2).hyperlink
noLink = None if noLinkObj is None else noLinkObj.target
print("no link:", noLink)
效率一般般,1800行左右的数据用了大约6秒。
任务完成,睡觉。
