【问题标题】:How to check for URL redirects in Google Sheets with Google Apps Script如何使用 Google Apps 脚本检查 Google 表格中的 URL 重定向
【发布时间】:2020-06-26 15:39:39
【问题描述】:

我一直在尝试使用 Google 表格中的 Google Apps 脚本运行一些 URL 重定向测试,我通过获得响应代码以及其中一些的最终重定向 URL 取得了成功,但大多数链接都不起作用。

我要检查的链接示例:

https://www.airbnb.com/rooms/4606613

https://www.airbnb.com/rooms/4661522

https://www.airbnb.com/rooms/6014647

https://www.airbnb.com/rooms/14452305

https://www.airbnb.com/rooms/15910617

我几乎需要检查这些链接是否会重定向到https://www.airbnb.com/s/homes

使用下面的脚本,我得到以下列表,这是不正确的,因为它们都会重定向到https://www.airbnb.com/s/homes

https://www.airbnb.com/rooms/4606613

https://www.airbnb.com/s/homes

https://www.airbnb.com/s/homes

https://www.airbnb.com/rooms/14452305

https://www.airbnb.com/rooms/15910617

网站似乎需要 1 秒来进行重定向,这可能是问题所在。

代码下方:

function urlProtocol(url){
  return URI(url).protocol()
}

function urlHostname(url){
  return URI(url).hostname()
}

function getRedirects(url) {
  eval(UrlFetchApp.fetch('https://rawgit.com/medialize/URI.js/gh-pages/src/URI.js').getContentText());

  var params = {
    'followRedirects': false,
    'muteHttpExceptions': true
  };

  var baseUrl = urlProtocol(url) + "://" + urlHostname(url),
      response = UrlFetchApp.fetch(url, params),
      responseCode = response.getResponseCode();

  if(response.getHeaders()['Location']){
    var redirectedUrl = getRedirects(baseUrl + response.getHeaders()['Location']);
    return redirectedUrl;
  } else {
    return url;
  }
}

【问题讨论】:

  • 代码上,followRedirects方法设置为false,和FetchApp有区别吗?因为我相信参数与评估相关
  • 好吧,我显然没有阅读您问题中的代码,对之前的评论感到抱歉(已经意识到并删除了)。不过,有一件事仍然有效 - 我会先检查响应代码是否为 3xx,然后检查标头,然后再递归。
  • 就目前而言,您的逻辑对我来说似乎很好。您能否添加一个未设置为重定向到 /home 的 URL 示例?
  • @OlegValter 一个示例 URL 是 airbnb.com/rooms/23861670 ,运行代码时我没有重定向,但大多数都一样。
  • 谢谢 - 你知道吗,我检查了自己,问题可能出在 airbnb 上。一些链接不一致地导致重定向。例如,15910617 房间有时会重定向到家,有时会加载所需的房间。

标签: google-apps-script google-sheets urlfetch


【解决方案1】:

似乎某些 URL 的最终重定向发生在页面加载之后。很可能有一个客户端脚本启动了window.location 的更改。因此,您的正确逻辑无法捕获此类页面。

更糟糕的是,加载后重定向似乎不一致,因为有时您提供的页面没有重定向到https://www.airbnb.com/s/homes。我能够阻止这种重定向的发生,因此该理论得到了证实 - 将更新它的确切原因。


除此之外,您还可以对脚本进行一些优化:

  1. 删除eval,实际上,删除整个库,除非你真的需要它(看看如何在两行中做同样的事情)。提高安全性是主要好处:没有eval() 外部脚本意味着更少的破坏可能性。
  2. 在查看 Location 标头之前检查 3xx 范围内的状态代码(作为预防措施)。
/**
 * 
 * @param {string} target 
 */
const getRedirects = (target) =>

  /**
   * @param {string}
   * @returns {boolean}
   */
  (url) => {

    if(url === target) {
      return false;
    }

    const response = UrlFetchApp.fetch(url, {
      'followRedirects': false,
      'muteHttpExceptions': true
    });

    const code = response.getResponseCode();

    let { Location } = response.getHeaders();

    if (code < 300 || code >= 400) {
      return true;
    }

    if (!Location) {
      return false;
    }

    if (/^\/\w+/.test(Location)) {
      const [protocol, , base] = url.split("/");
      Location = `${protocol}//${base}${Location}`;
    }

    console.log(Location);
    
    return getRedirects(target)(Location);
  };

const testRedirects = () => {

  const redirectsToHome = getRedirects("https://www.airbnb.com/s/homes");

  const accessible = [
    "https://www.airbnb.com/rooms/23861670",
    "https://www.airbnb.com/rooms/4606613",
    "https://www.airbnb.com/rooms/4661522",
    "https://www.airbnb.com/rooms/6014647",
    "https://www.airbnb.com/rooms/14452305",
    "https://www.airbnb.com/rooms/15910617"
  ].filter(redirectsToHome);

  console.log(accessible);
};

由于该函数是 custom function 的说明,您可以添加一个包装函数,该函数将用作公共 API,您可以在调用该实用程序的单元格中引用它,如下所示:

const checkIfRedirects = (source, target = "https://www.airbnb.com/s/homes") => getRedirects(target)(source);

然后您可以像使用公式一样使用它:

=checkIfRedirects(A20)

【讨论】:

  • 由于我将在单元格值之外运行它,我应该像 UDF (=getRedirects(A2)) 一样使用它吗?我不太了解过滤方法声明
  • 哦,我没有让你想使用自定义函数 - 我主要使用区域和过滤器进行演示。如果用作CF,应该重新设计一下
  • 无论是自定义函数还是只运行脚本,我的问题是我应该如何运行它,以及如何检索单元格中的 Urls 列表,例如:docs.google.com/spreadsheets/d/…
  • @Excelsson - 好吧,当获取成功并且一个空字符串(或在这种情况下您想要返回的任何内容)而不是 false。至于如何调用单元格 - 在脚本中查看更新 - 因为你想要一个值列表,我会使用它与 map 方法配对
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 2015-12-30
相关资源
最近更新 更多