Pandas read_excel 与超链接

问题描述 投票:0回答:5

我有一个 Excel 电子表格,正在将其读入 Pandas DataFrame:

df = pd.read_excel("file.xls")

但是,电子表格的其中一列包含具有与其关联的超链接的文本。如何访问 Pandas 中的底层超链接?

excel pandas
5个回答
15
投票

这可以用 openpyxl 来完成,我不确定 Pandas 是否可以。这是我的做法:

import openpyxl

wb = openpyxl.load_workbook('yourfile.xlsm')
sheets = wb.sheetnames
ws = wb[sheets[0]]
# Deprecation warning
# ws = wb.get_sheet_by_name('Sheet1')
print(ws.cell(row=2, column=1).hyperlink.target)

您还可以使用 iPython,并设置一个等于超链接对象的变量:

t = ws.cell(row=2, column=1).hyperlink

然后执行

t.
并按 Tab 键查看可对对象执行的操作或从对象访问的所有选项。


3
投票

快速猴子修补,没有转换器或类似的东西,如果您想将所有带有超链接的单元格视为超链接,更复杂的方式,我想,至少能够选择,哪些列视为超链接或收集数据,或保存以某种方式,数据和超链接都在数据帧的同一单元格中。并使用转换器,不知道。 (顺便说一句,我也玩了

data_only
keep_links
,没有帮助,只改变
read_only
结果就可以了,我想它会减慢你的代码速度)。

P.S.:仅适用于 xlsx,即引擎是 openpyxl

P.P.S.:如果您将来阅读此评论并发布 https://github.com/pandas-dev/pandas/issues/13439 仍然打开,请不要忘记查看

_convert_cell
load_workbook
中的更改在
pandas.io.excel._openpyxl
并相应地更新它们。

import pandas
from pandas.io.excel._openpyxl import OpenpyxlReader
import numpy as np
from pandas._typing import FilePathOrBuffer, Scalar


def _convert_cell(self, cell, convert_float: bool) -> Scalar:
    from openpyxl.cell.cell import TYPE_BOOL, TYPE_ERROR, TYPE_NUMERIC
    # here we adding this hyperlink support:
    if cell.hyperlink and cell.hyperlink.target:
        return cell.hyperlink.target
        # just for example, you able to return both value and hyperlink,
        # comment return above and uncomment return below
        # btw this may hurt you on parsing values, if symbols "|||" in value or hyperlink.
        # return f'{cell.value}|||{cell.hyperlink.target}'
    # here starts original code, except for "if" became "elif"
    elif cell.is_date:
        return cell.value
    elif cell.data_type == TYPE_ERROR:
        return np.nan
    elif cell.data_type == TYPE_BOOL:
        return bool(cell.value)
    elif cell.value is None:
        return ""  # compat with xlrd
    elif cell.data_type == TYPE_NUMERIC:
        # GH5394
        if convert_float:
            val = int(cell.value)
            if val == cell.value:
                return val
        else:
            return float(cell.value)

    return cell.value


def load_workbook(self, filepath_or_buffer: FilePathOrBuffer):
    from openpyxl import load_workbook
    # had to change read_only to False:
    return load_workbook(
        filepath_or_buffer, read_only=False, data_only=True, keep_links=False
    )


OpenpyxlReader._convert_cell = _convert_cell
OpenpyxlReader.load_workbook = load_workbook

在你的Python文件中添加上面的内容后,你将能够调用

df = pandas.read_excel(input_file)

写完所有这些东西后,我想到,也许单独使用 openpyxl 会更容易、更干净 ^_^


1
投票

正如 slaw 所评论的,它不抓取超链接,而只抓取文本

此处text.xlsx包含第9列中的链接

from openpyxl import load_workbook
workbook = load_workbook('test.xlsx')
worksheet = workbook.active

column_indices = [9]

for row in range(2, worksheet.max_row + 1):
    for col in column_indices:
        filelocation = worksheet.cell(column=col, row=row)  # this is hyperlink
        text = worksheet.cell(column=col + 1, row=row)  # thi is your text 
        worksheet.cell(column=col + 1, row=row).value = '=HYPERLINK("' + filelocation.value + '","' + text.value + '")'

workbook.save('test.xlsx')

0
投票

你不能在 pandas 中做到这一点。您可以尝试使用其他旨在处理 Excel 文件的库


0
投票

当我尝试使用 pandas 复制 Excel 文件时,我遇到了同样的问题。我想出了以下代码来解决这个问题。

import pandas as pd
import openpyxl


def get_columnn_data_list(wb,column_number):
    data = []
    ws = wb["Sheet1"]

    for row in ws.iter_rows(min_row=2):
        value = row[column_number].value
        data.append(value)

    return data


df = pd.read_excel("input.xlsx")
wb = openpyxl.load_workbook("input.xlsx")

column_number = 3 # This is the number(index starts from 1) of the column with hyperlinks.
column_name = "column_name" # This is the name of the column with hyperlinks. I.E : the column name of column_number

df[column_name] = get_columnn_data_list(wb,column_number)

这里发生的是,我们手动迭代 Excel 工作表,并使用

get_columnn_data_list
函数收集带有给定列号的超链接的单元格值。根据我们得到的结果,我们正在更新数据框的相关列。我们得到的结果的形式为

=HYPERLINK("https://www.example.com", "visible_text")

因此,如果您想获取 url 或可见文本,您可能需要自己进行一些简单的字符串拆分。

© www.soinside.com 2019 - 2024. All rights reserved.