如何使用 Google Apps 脚本检查 Google 表格中的 URL 重定向
How to check for URL redirects in Google Sheets with Google Apps Script
我一直在尝试 运行 使用 Google Apps 脚本在 Google 表格中进行一些 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;
}
}
某些 URL 的最终重定向似乎发生在页面加载之后。很可能有一个 client-side 脚本启动 window.location
的更改。因此,您的正确逻辑无法捕获此类页面。
更糟糕的是,after-load 重定向似乎不一致,因为有时您提供的页面没有重定向到 https://www.airbnb.com/s/homes
。我能够阻止此重定向的发生,因此该理论得到证实 - 将更新确切的原因。
除此之外,您还可以对脚本进行多项优化:
- 去掉
eval
,实际上,去掉整个库,除非你真的需要它(看看如何在两行中做同样的事情)。提高安全性是主要好处:没有 eval()
外部脚本意味着破坏的可能性较小。
- 在查看
Location
header 之前检查 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 后,您可以添加一个包装函数作为 public API,您可以在将调用实用程序,像这样:
const checkIfRedirects = (source, target = "https://www.airbnb.com/s/homes") => getRedirects(target)(source);
然后您可以像使用公式一样使用它:
=checkIfRedirects(A20)
我一直在尝试 运行 使用 Google Apps 脚本在 Google 表格中进行一些 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;
}
}
某些 URL 的最终重定向似乎发生在页面加载之后。很可能有一个 client-side 脚本启动 window.location
的更改。因此,您的正确逻辑无法捕获此类页面。
更糟糕的是,after-load 重定向似乎不一致,因为有时您提供的页面没有重定向到 https://www.airbnb.com/s/homes
。我能够阻止此重定向的发生,因此该理论得到证实 - 将更新确切的原因。
除此之外,您还可以对脚本进行多项优化:
- 去掉
eval
,实际上,去掉整个库,除非你真的需要它(看看如何在两行中做同样的事情)。提高安全性是主要好处:没有eval()
外部脚本意味着破坏的可能性较小。 - 在查看
Location
header 之前检查 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 后,您可以添加一个包装函数作为 public API,您可以在将调用实用程序,像这样:
const checkIfRedirects = (source, target = "https://www.airbnb.com/s/homes") => getRedirects(target)(source);
然后您可以像使用公式一样使用它:
=checkIfRedirects(A20)