如何使用公式从Google表格中提取链接中的URL?

71

我从一个网站复制了一系列超链接,并将它们粘贴到 Google Sheet 中。这些值显示为链接文本,而不是超链接公式,并且仍然正确地链接。对于每一行,我想仅提取URL(而不是友好的文本),并将其插入相邻的列中。如何使用公式来完成这个操作?

例如:

=SOMEFUNCTION(cellThatHoldsLink, returnedURLOnly)

这种情况及类似情况并不适用,因为粘贴的数据不是公式。我可以接受脚本(GAS)或其他任何解决方案,但如果可以使用公式解决会更好。我已经找到了许多超链接操作脚本,但没有针对这种特定情况的,甚至找不到如何访问保存该网址的属性。谢谢。


1
提供一些单元格中内容的真实示例。这样别人就可以测试输出了。 - Alan Wells
1
Sandy,这是一个例子:https://docs.google.com/spreadsheets/d/1KksyZwP4CBfmX8YN7BK0jcNY3iFvXYZTUZQnA6TfT0g/edit#gid=0 - iamtoc
你最开始是在那个位置粘贴了一些链接或超链接,之后删除并重新粘贴的吗? - Aurielle Perlmann
2
是的 - 我每天都使用Linkclump - 它是一个很棒的Chrome插件 - 或者如果您分享了获取链接的源URL,我会向您展示如何在您的表格上使用一个酷炫的技巧。 - Aurielle Perlmann
linkclump 能够节省很多时间。 - macasas
显示剩余3条评论
16个回答

43

2020年更新后,我在网上找到的所有代码都失效了,因此这是我的贡献:

/** 
 * Returns the URL of a hyperlinked cell, if it's entered with control + k. 
 * Author: @Frederico Schardong based on https://support.google.com/docs/thread/28558721?hl=en&msgid=28927581 and https://github.com/andrebradshaw/utilities/blob/master/google_apps/convertHiddenLinks.gs 
 * Supports ranges
 */
function linkURL(reference) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var formula = SpreadsheetApp.getActiveRange().getFormula();
  var args = formula.match(/=\w+\((.*)\)/i);
  try {
    var range = sheet.getRange(args[1]);
  }
  catch(e) {
    throw new Error(args[1] + ' is not a valid range');
  }
  
  var formulas = range.getRichTextValues();
  var output = [];
  for (var i = 0; i < formulas.length; i++) {
    var row = [];
    for (var j = 0; j < formulas[0].length; j++) {
      row.push(formulas[i][j].getLinkUrl());
    }
    output.push(row);
  }
  return output
}

3
太好了!非常感谢!我还有一个特殊情况要解决,我在同一个“公式”中有多个链接(formulas [0] .length == 1)。你知道怎么解决吗? - Kikiwa
6
终于找到了解决办法,使用getRuns()方法完成了工作。这是我“具体”的脚本:https://gist.github.com/glureau/833d83099cb74efc937f9afddba2cca4 ,你只需调整所需的格式即可。 - Kikiwa
1
我确认。这在Google表格中粘贴超链接时完全按预期工作。谢谢! - David Finster
2
对于嵌入式URL(不像HYPERLINK=...那样),我首先使用这个插件https://extract-urls.contributor.pw/将它们转换,然后使用`linkURL`获取实际的URL。 - cmantas
@Kikiwa的代码片段在2021年对我最有用。 - arbolitoloco
显示剩余3条评论

30

如果您的超链接是在另一个单元格中以公式的形式指定的——例如假设单元格A1包含公式=HYPERLINK("https://www.wikipedia.org/","Wikipedia"),您可以使用正则表达式提取链接文本。您需要做的就是:

=REGEXEXTRACT(FORMULATEXT(A1),"""(.+)"",")

这个公式将产生以下结果:

https://www.wikipedia.org/

不需要自定义函数。


1
=REGEXEXTRACT(FORMULATEXT(A1),"""(.+?)""") 更好,因为链接文本是可选参数,可能没有逗号,而且REGEXEXTRACT仅返回第一个匹配项。 - vstepaniuk
2
非常棒,当超链接是用=hyperlink("https ...," ...")创建时,它能够很好地工作。但不幸的是,当超链接从其他地方粘贴过来时,它就无法正常工作了。有没有可能将已粘贴的超链接转换为使用公式=hyperlink()的超链接呢?也许可以通过宏实现吗? - Adolfo Correa
  1. 上述的=REGEXEXTRACT()对于=hyperlink()的提取非常棒,感谢@Jordan。
  2. @AdolfoCorrea - 你是否收到了关于你上面问题的回复/答案/反馈?我也很感兴趣。
- Johnny Utahh
1
@JohnnyUtahh 我还没有找到解决那个问题的方法。如果你找到了,请在这里评论。如果我找到了解决这个问题的方法,我也会这样做。 - Adolfo Correa
有点晚了,但如果你一次从一个网站复制了很多链接到电子表格中,你可以使用这个扩展程序在Firefox或Chrome上代替 https://addons.mozilla.org/en-US/firefox/addon/copy-selected-links/ - Matt
非常感谢!我刚刚花了太多时间尝试各种在线教程,但都失败了,然后遇到了这个。谢谢! - benny

23

这可以通过将链接粘贴到自动创建的链接中完成,或者使用link button按钮,转到“工具” ->“脚本编辑器”,并创建以下脚本:

function GETLINK(input){
return SpreadsheetApp.getActiveSheet().getRange(input).getRichTextValue().getLinkUrl();
}

如果单元格A1中有链接,则需要将其引用为=GETLINK("A1")。如果您有很多链接,那么这不会动态更新,因此请使用=GETLINK(cell("Address",A1))来解决该问题。

感谢reddit上的morrisjr1989。


2
这个GETLINK是今天唯一帮助我的东西。然而,由于我所有链接的值都在B列中,最终我使用了=GETLINK("B"&ROW())。 (在长时间思考后,才明白为什么例如=GETLINK(B2)不能直接工作。) - marco
这会引发一个异常 :(异常:参数不能为空:a1Notation GETLINK @ Code.gs:3 - cmantas
@cmantas A1只是一个例子。你需要使用包含链接的单元格的地址。 - MrG
2
=GETLINK("B"&ROW()) 对我很有效。我通过转到扩展 -> 应用脚本并将脚本粘贴在那里找到了脚本编辑器。 - nicolasDevDes

7
内置的SpreadsheetApp服务似乎不支持提取这样的URL,但“高级”Sheets服务可以。
根据谷歌的说明启用高级Sheets服务,然后尝试此代码:
function onOpen() {
  var menu = SpreadsheetApp.getUi().createMenu("Extract URLs");
  menu.addItem("Process =EXTRACT_URL(A1) formulas", "processFormulas");
  menu.addToUi();
}

function EXTRACT_URL() {
  return SpreadsheetApp.getActiveRange().getFormula();
}

function processFormulas() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  var rows = sheet.getDataRange().getFormulas();
  for (var r = 0; r < rows.length; r++) {
    var row = rows[r];
    for (var c = 0; c < row.length; c++) {
      var formula = row[c];
      if (formula) {
        var matched = formula.match(/^=EXTRACT_URL\((.*)\)$/i);
        if (matched) {
          var targetRange = matched[1];
          if (targetRange.indexOf("!") < 0) {
            targetRange = sheet.getName() + "!" + targetRange;
          }
          var result = Sheets.Spreadsheets.get(spreadsheet.getId(), {
            ranges: targetRange,
            fields: 'sheets.data.rowData.values.hyperlink'
          });
          try {
            var value = result.sheets[0].data[0].rowData[0].values[0].hyperlink;
            sheet.getRange(r + 1, c + 1).setValue(value);
          } catch (e) {
            // no hyperlink; just ignore
          }
        }
      }
    }
  }
}

这将创建一个自定义函数,名为EXTRACT_URL,您应该使用包含链接的单元格的引用来调用它;例如,=EXTRACT_URL(B3)

不幸的是,它不能立即起作用,因为高级表服务不能直接被自定义函数使用。因此,此脚本会在电子表格菜单栏中添加一个名为“提取URL”的菜单,其中有一个标记为“处理=EXTRACT_URL(A1)公式”的菜单项。当您单击它时,它将替换所有使用EXTRACT_URL函数的地方,并显示URL本身。


1
这个可以工作,但是如果一次处理太多的话,我会收到一个错误信息:“sheets.googleapis.com”的配额“ReadGroup”和限制“USER-100s”的令牌不足。值得注意的是,这是一次性操作,因为它将公式替换为结果。 - Simon D
是的,这个可以工作!但由于已经提到的配额问题,它非常慢。如何解决? - Joe Ercolino
@JoeErcolino 你可以通过更新代码以接受多个值并一次性写入工作表来加快速度。这样做,我能够在0.793秒内获取、应用额外的处理并打印出184个值。 - Diego

6
你可以使用importxml来提取整个数据表及其内容,方法如下:
=IMPORTXML(A1,"//tr")

在此之后,我们将标签中的URL字符串拉入其中。

=IMPORTXML(A1,"//tr/td[1]/a/@href")

最后,将字符串与原始域名连接起来,创建您的超链接。
=ARRAYFORMULA("http://www.bnilouisiana.com/"&INDIRECT("A2:A"&COUNTA(A2:A)))

我尝试过只在单元格中放置URL而没有超链接公式,但是该单元格确实是一个链接。我将其复制到新工作表中,并导入了所有数据,但只有字符串“url”,而不是链接。这里有一些单元格的小例子:https://docs.google.com/a/fuzion.co.nz/spreadsheets/d/1amgIB30WpCLqT0s_EDgw3w8DxkTa4OlMSFKgCBZZHn0/edit?usp=sharing - petednz - fuzion
面向对象编程中,点击“添加评论”太快了。您认为上述情况应该起作用吗? - petednz - fuzion
你还没分享文档@petednz-fuzion。 - Aurielle Perlmann
感谢您的尝试协助并确认这是一个“无望”的情况,正如您在私信中所说:“它们不是字符串URL”。谢谢。 - petednz - fuzion
1
第二个公式。但我也看到过一些帖子说这个函数有时候不起作用。 - Andy
你是从和 OP 完全相同的数据源获取数据吗?如果不起作用,那么这是因为每个 URL 或网站源的 XPath 都会有所不同。@andy - Aurielle Perlmann

4

通过一些研究,我发现Google表格中有两种类型的链接:

  1. 超链接(例如公式:=HYPERLINK=("www.google.com")
  2. “嵌入式”链接(你看不到或编辑公式)

对于第一种类型,您可以直接使用@frederico-schardong的linkURL

对于第二种类型,您可以首先使用提取URLs插件,然后再使用linkURL


Extract URLS插件可以帮助我在看不到URL的情况下提取它们,非常感谢。 - Vicente Matus

2

如果您喜欢使用Google Apps Script,则可以使用以下功能从文本中获取超链接。当您传递单元格时,应该用双引号发送。例如:=GETURL("A4")可以获取A4的超链接。

function GETURL(input) {
  var range = SpreadsheetApp.getActiveSheet().getRange(input);
  var url = /"(.*?)"/.exec(range.getFormulaR1C1())[1];
  return url;
}

请参考此处的示例。

编辑:忽略本答案。仅当单元格中链接了网址时才有效。


如果你看他的例子,这样做是行不通的——链接不是超链接公式,而只是带有链接但没有可见的“链接公式”的文本。 - Aurielle Perlmann
哦!明白了!抱歉,这对他的例子不起作用。 - Abdul Hameed
1
@iamtoc 我在上方留了评论,如果你分享一个样本链接,我会向你展示一个公式,以便通过XPath自动提取所有这些URL。 - Aurielle Perlmann
1
@iamtoc 给您的示例文档添加了一个工作表,并在其中放置了 XML 提取内容 - 我只能假定您不仅想要提取一页 - 如果您有第二个链接,那么我们可以自动拉取所有页面,请告诉我其 URL 模式是什么。 - Aurielle Perlmann
1
还添加了4个注释以澄清公式。 - Aurielle Perlmann
显示剩余2条评论

2

找到了一个有效的答案在Google Groups上(作者是Troy):

  1. 发布您的电子表格(复制URL)
  2. 创建一个新电子表格并使用IMPORTXML函数(将URL替换为步骤1中获取的URL)
  3. 您会得到数据-然后可以将值复制并粘贴到需要它们的位置
  4. 取消发布电子表格(如果您不想公开)

也可以通过脚本完成,但我现在没有时间。 :)


1

2022年更新:

  1. 录制一段虚拟宏,并将其保存为“ExtractLinks”。
  2. 然后编辑该宏,以进入脚本编辑器。
  3. 然后粘贴以下内容并保存:
function ExtractLinks() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  var rows = sheet.getActiveRange().getValues();
  var z = sheet.getActiveRange().getRowIndex();
  var s = sheet.getActiveRange().getColumn();

  for (var r = 0; r < rows.length; r++) {
    var row = rows[r];
    for (var c = 0; c < row.length; c++) {
      var val = row[c];
      if (val) {
        var targetRange = sheet.getRange(r+z, c+s).getA1Notation();
        var result = Sheets.Spreadsheets.get(spreadsheet.getId(), {
          ranges: sheet.getName() + "!" + targetRange,
          fields: 'sheets.data.rowData.values'
        });
        if (result.sheets[0].data[0].rowData[0].values[0].hyperlink) {
          var url = result.sheets[0].data[0].rowData[0].values[0].hyperlink;
          var text = result.sheets[0].data[0].rowData[0].values[0].effectiveValue.stringValue;
          sheet.getRange(r + z, c + s).setValue(''+url);
        }
      }
    }
  }
};
  1. 您可以从扩展 > 宏 > 提取链接 运行该宏。

这是Natso代码的一种适应方式,可以用于一系列操作。


另外还有两点需要注意:确保已开启Sheets API,并注意每分钟请求配额限制。 - Michael De Soto

0
你可以创建一个名为“ExtractURLs”的宏,然后使用以下代码进行编辑,该代码解析活动单元格中的一致文本样式块,尝试检索URL,并将其粘贴到相邻单元格中。

    function ExtractURLs() {
      
      var spreadsheet = SpreadsheetApp.getActive();
    
      var richTextCell = SpreadsheetApp.getActiveRange().getRichTextValue();
    
      var richTextStrings = richTextCell.getRuns();
      
      var linksStr = "";
      var linkCell = spreadsheet.getCurrentCell()
      var link = "";
      var richTextString = "";
    
      for (var x=0; x < richTextStrings.length; x++)
      {
        richTextString = richTextStrings[x].getText();
        
        Logger.log(richTextString);
    
        link = richTextStrings[x].getLinkUrl();
        Logger.log(link);
    
        if (link != null)
        {
         linksStr += link;
         linksStr += ', '; 
        }  
      }  
    
      var targetCell = linkCell.offset(0, 1).activate();
      targetCell.setValue(linksStr.substr(0,linksStr.length-2));
    };


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接