访问(新样式,public)Google sheet 作为 JSON
Accessing a (new-style, public) Google sheet as JSON
如何访问(新式)Google sheet a JSON 的内容?我的目标是从 JavaScript 访问值,因此我需要能够通过 HTTP 下载 JSON。
示例:如何从 this sheet 下载数据为 JSON?
我试图通过网络搜索找到答案,但最终失败了:
网络上的许多教程都是从在 url 中查找 key=...
值的指令开始的。我导出sheet时得到的URL是https://docs.google.com/spreadsheets/d/1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI/pubhtml?gid=1822753188&single=true
,里面没有key=...
。
"Accessing A Public Google Sheet" seems to indicate that I should try https://docs.google.com/spreadsheets/d/1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI/export?format=csv&id=1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI&gid=1822753188
的答案以获得 CSV 版本,但这对我不起作用:我得到的是登录页面而不是数据。
我找到了使用 Google Apps 脚本的方法,但这些方法似乎需要用户在浏览器中进行一些操作,而不是提供下载 link.
我终于(有点)解决了我的问题。仅供将来参考,以防其他人遇到同样的麻烦,这里是我想出的解决方案:
要使作品sheet可公开访问,需要使作品sheet可公开访问。这是在 Google 表格网络界面中使用菜单条目 File > Publish to the web ... > link > publish
完成的。可以发布整个传播sheet 或个人作品sheets.
API 以编程方式访问 Google 工作表中的数据在 Google Sheets API web pages 中进行了描述。此 API 使用 URLS 形式 https://spreadsheets.google.com/feeds/.../
key/
worksheetId/...
。有点奇怪, key 和 worksheetId 的含义似乎没有在 API 文档中解释。
我的实验表明,key 值可以通过用于通过网络界面访问 sheet 的 URLs 的一部分找到(另见 here)。关键是 /d/
之后的所有内容,直到下一个斜线。对于题目中的spreadsheet,key就是1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI
。 worksheetId好像是一个整数,给出了作品sheet在spreadsheet中的位置。对于问题中的示例,必须知道显示的 sheet 是第二个作品 sheet,在这种情况下 worksheetId 是2
.
API 定义了 public
和 private
请求。要在没有身份验证的情况下访问导出的资源,必须使用 public
请求。
从价差sheet 中获取数据的 API 调用在 "Retrieving a list-based feed" 部分进行了说明(单击 "Protocol" 选项卡例子)。 URL 要求从问题中的 spreadsheet 中提取数据是
对此 URL returns 数据的 HTTP GET 请求为 XML。 (我还没有找到获取数据的方法 JSON。)
针对跨站点请求的通常保护措施使得通过网络应用程序中的 JavaScript XML RPC 调用访问数据变得困难。解决此问题的一种方法是通过 Web 服务器代理 API 调用( 例如 使用 nginx 的 proxy_pass directive)。
以上步骤至少部分解决了问题中的问题。唯一的困难是数据返回为 XML 而不是 JSON。由于 API 文档没有提到 JSON,也许无法再提取这种格式的数据?
编辑: (2021 年 8 月 17 日)随着表格 v4 的推出,原始答案中的端点已被弃用。下面包含更新的端点和示例脚本:
更新解决方案
"https://docs.google.com/spreadsheets/d/" + spreadsheetId + "/gviz/tq?tqx=out:json&gid=0";
如果您只想要第一个 sheet,从技术上讲,您不必包含 gid
,但如果您想使用该参数,则可以指定另一个 sheet。
这是一个示例脚本,用于将 Spreadsheet 的值检索为 JSON,然后解析为 header 行和值。
var sf = "https://docs.google.com/spreadsheets/d/1l7VfPOI3TYtPuBZlZ-JMMiZW1OK6rzIBt8RFd6KmwbA/gviz/tq?tqx=out:json";
$.ajax({url: sf, type: 'GET', dataType: 'text'})
.done(function(data) {
const r = data.match(/google\.visualization\.Query\.setResponse\(([\s\S\w]+)\)/);
if (r && r.length == 2) {
const obj = JSON.parse(r[1]);
const table = obj.table;
const header = table.cols.map(({label}) => label);
const rows = table.rows.map(({c}) => c.map(({v}) => v));
console.log(header);
console.log(rows);
}
})
.fail((e) => console.log(e.status));
原解
注意:这不再有效,因为表格 v3 已于 2021 年 8 月弃用。
以下是使用相同 URL 参数获取 JSON 的方法:
"https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/od6/public/values?alt=json";
感谢 @jochen 的答案,一直到 XML "https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/od6/public/" + sheetID;
正如@jochen 的回答所解释的那样,这个 sheetID
是基于 sheet 中 sheet 的顺序 sheet.
此处一个更快的解决方案是使用此 https://gist.github.com/ronaldsmartin/47f5239ab1834c47088e 环绕您现有的价差sheet。
您首先需要将 sheet 访问权限更改为 Anyone with link can View
将 id
和 sheet
html 参数添加到下面的 URL 中。
https://script.google.com/macros/s/AKfycbzGvKKUIaqsMuCj7-A2YRhR-f7GZjl4kSxSN1YyLkS01_CfiyE/exec
例如:您的 id
是您的 sheet id,即
1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI
你的 sheet 即
Sheet2
在您的情况下,您实际上可以在 json 处看到您的数据
为了安全起见,您应该将上面 github 要点中的代码 sheetAsJson.gs
作为您自己的代码部署在您的 Google 驱动器中。
如果您想使用最新的 API (v4),您需要执行以下操作:
- 生成传播sheets API 密钥(参见下面的说明)。
- 让您的 sheet public 易于访问。
使用以下形式的请求:
https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/RANGE?key=API_KEY
然后您将得到干净的 JSON 回复:
{
"range": "Sheet1!A1:D5",
"majorDimension": "ROWS",
"values": [
["Item", "Cost", "Stocked", "Ship Date"],
["Wheel", ".50", "4", "3/1/2016"],
["Door", "", "2", "3/15/2016"],
["Engine", "0", "1", "30/20/2016"],
["Totals", "5.5", "7", "3/20/2016"]
],
}
请注意,如果要指定页面的全部内容,则 Sheet1
等标识符为 perfectly valid。
有关详细信息,请参阅 Basic Reading。
从 v4 开始 API,all requests must be accompanied 通过标识符(例如 API 键):
Requests to the Google Sheets API for public data must be accompanied by an identifier, which can be an API key or an access token.
按照 linked 文档中的步骤在 credentials page 上创建一个 API 键。
确保:
- 在 Google 云平台上创建一个新应用程序。
- 创建一个新的 API 密钥。
- 添加 Google 张 API。 (API 管理器 > 仪表板 > 启用 API)
请注意,您可以 still access public data 而无需强制用户登录:
In the new Sheets API v4, there is no explicit declaration of visibility. API calls are made using spreadsheet IDs. If the application does not have permission to access specified spreadsheet, an error is returned. Otherwise the call proceeds.
请注意,您不需要将sheet发布到网络上。您需要做的就是确保 拥有 link 的任何人都可以访问 sheet.
(即当您在 Google 工作表 API 上单击 创建凭据 时,选择其他非 UI、用户数据,以及它说 "User data cannot be accessed from a platform without a UI because it requires user interaction for sign-in." 您可以安全地忽略该消息。API 密钥是您真正需要的,因为这是 public 数据。)
常见错误信息:
The request is missing a valid API key.
您没有在调用中包含 key=
参数。
API key not valid. Please pass a valid API key.
Google developers console
您提供的 API 密钥不正确。确保您输入的密钥正确。如果您还没有密钥,请转到 Google developers console 并创建一个。
API Key not found. Please pass a valid API key.
Google developer console API key
您的 API 密钥可能是正确的,但您很可能没有添加 Google 表格权限。转到 Google 开发人员控制台 API 关键页面并添加 sheets 权限。
The caller does not have permission
您的 sheet 未设置为 public 仅可访问。
这是解决方案
- 在文档 url 中记下您的 sheet ID(不要使用已发布的 url 来查找 ID!)
- 发布您的 sheet,就像 html 页面一样
- 使用第 1 步中的 ID,
- 然后把它放在这个urlhttps://spreadsheets.google.com/feeds/cells/{id}/1/public/full?alt=json
/1 表示文档中的第一个 sheet
如何访问(新式)Google sheet a JSON 的内容?我的目标是从 JavaScript 访问值,因此我需要能够通过 HTTP 下载 JSON。
示例:如何从 this sheet 下载数据为 JSON?
我试图通过网络搜索找到答案,但最终失败了:
网络上的许多教程都是从在 url 中查找
key=...
值的指令开始的。我导出sheet时得到的URL是https://docs.google.com/spreadsheets/d/1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI/pubhtml?gid=1822753188&single=true
,里面没有key=...
。"Accessing A Public Google Sheet" seems to indicate that I should try
https://docs.google.com/spreadsheets/d/1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI/export?format=csv&id=1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI&gid=1822753188
的答案以获得 CSV 版本,但这对我不起作用:我得到的是登录页面而不是数据。我找到了使用 Google Apps 脚本的方法,但这些方法似乎需要用户在浏览器中进行一些操作,而不是提供下载 link.
我终于(有点)解决了我的问题。仅供将来参考,以防其他人遇到同样的麻烦,这里是我想出的解决方案:
要使作品sheet可公开访问,需要使作品sheet可公开访问。这是在 Google 表格网络界面中使用菜单条目
File > Publish to the web ... > link > publish
完成的。可以发布整个传播sheet 或个人作品sheets.API 以编程方式访问 Google 工作表中的数据在 Google Sheets API web pages 中进行了描述。此 API 使用 URLS 形式
https://spreadsheets.google.com/feeds/.../
key/
worksheetId/...
。有点奇怪, key 和 worksheetId 的含义似乎没有在 API 文档中解释。我的实验表明,key 值可以通过用于通过网络界面访问 sheet 的 URLs 的一部分找到(另见 here)。关键是
/d/
之后的所有内容,直到下一个斜线。对于题目中的spreadsheet,key就是1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI
。 worksheetId好像是一个整数,给出了作品sheet在spreadsheet中的位置。对于问题中的示例,必须知道显示的 sheet 是第二个作品 sheet,在这种情况下 worksheetId 是2
.API 定义了
public
和private
请求。要在没有身份验证的情况下访问导出的资源,必须使用public
请求。从价差sheet 中获取数据的 API 调用在 "Retrieving a list-based feed" 部分进行了说明(单击 "Protocol" 选项卡例子)。 URL 要求从问题中的 spreadsheet 中提取数据是
对此 URL returns 数据的 HTTP GET 请求为 XML。 (我还没有找到获取数据的方法 JSON。)
针对跨站点请求的通常保护措施使得通过网络应用程序中的 JavaScript XML RPC 调用访问数据变得困难。解决此问题的一种方法是通过 Web 服务器代理 API 调用( 例如 使用 nginx 的 proxy_pass directive)。
以上步骤至少部分解决了问题中的问题。唯一的困难是数据返回为 XML 而不是 JSON。由于 API 文档没有提到 JSON,也许无法再提取这种格式的数据?
编辑: (2021 年 8 月 17 日)随着表格 v4 的推出,原始答案中的端点已被弃用。下面包含更新的端点和示例脚本:
更新解决方案
"https://docs.google.com/spreadsheets/d/" + spreadsheetId + "/gviz/tq?tqx=out:json&gid=0";
如果您只想要第一个 sheet,从技术上讲,您不必包含 gid
,但如果您想使用该参数,则可以指定另一个 sheet。
这是一个示例脚本,用于将 Spreadsheet 的值检索为 JSON,然后解析为 header 行和值。
var sf = "https://docs.google.com/spreadsheets/d/1l7VfPOI3TYtPuBZlZ-JMMiZW1OK6rzIBt8RFd6KmwbA/gviz/tq?tqx=out:json";
$.ajax({url: sf, type: 'GET', dataType: 'text'})
.done(function(data) {
const r = data.match(/google\.visualization\.Query\.setResponse\(([\s\S\w]+)\)/);
if (r && r.length == 2) {
const obj = JSON.parse(r[1]);
const table = obj.table;
const header = table.cols.map(({label}) => label);
const rows = table.rows.map(({c}) => c.map(({v}) => v));
console.log(header);
console.log(rows);
}
})
.fail((e) => console.log(e.status));
原解
注意:这不再有效,因为表格 v3 已于 2021 年 8 月弃用。
以下是使用相同 URL 参数获取 JSON 的方法:
"https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/od6/public/values?alt=json";
感谢 @jochen 的答案,一直到 XML "https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/od6/public/" + sheetID;
正如@jochen 的回答所解释的那样,这个 sheetID
是基于 sheet 中 sheet 的顺序 sheet.
此处一个更快的解决方案是使用此 https://gist.github.com/ronaldsmartin/47f5239ab1834c47088e 环绕您现有的价差sheet。
您首先需要将 sheet 访问权限更改为 Anyone with link can View
将 id
和 sheet
html 参数添加到下面的 URL 中。
https://script.google.com/macros/s/AKfycbzGvKKUIaqsMuCj7-A2YRhR-f7GZjl4kSxSN1YyLkS01_CfiyE/exec
例如:您的 id
是您的 sheet id,即
1mhv1lpzufTruZhzrY-ms0ciDVKYiFJLWCMpi4OOuqvI
你的 sheet 即
Sheet2
在您的情况下,您实际上可以在 json 处看到您的数据
为了安全起见,您应该将上面 github 要点中的代码 sheetAsJson.gs
作为您自己的代码部署在您的 Google 驱动器中。
如果您想使用最新的 API (v4),您需要执行以下操作:
- 生成传播sheets API 密钥(参见下面的说明)。
- 让您的 sheet public 易于访问。
使用以下形式的请求:
https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/RANGE?key=API_KEY
然后您将得到干净的 JSON 回复:
{
"range": "Sheet1!A1:D5",
"majorDimension": "ROWS",
"values": [
["Item", "Cost", "Stocked", "Ship Date"],
["Wheel", ".50", "4", "3/1/2016"],
["Door", "", "2", "3/15/2016"],
["Engine", "0", "1", "30/20/2016"],
["Totals", "5.5", "7", "3/20/2016"]
],
}
请注意,如果要指定页面的全部内容,则 Sheet1
等标识符为 perfectly valid。
有关详细信息,请参阅 Basic Reading。
从 v4 开始 API,all requests must be accompanied 通过标识符(例如 API 键):
Requests to the Google Sheets API for public data must be accompanied by an identifier, which can be an API key or an access token.
按照 linked 文档中的步骤在 credentials page 上创建一个 API 键。
确保:
- 在 Google 云平台上创建一个新应用程序。
- 创建一个新的 API 密钥。
- 添加 Google 张 API。 (API 管理器 > 仪表板 > 启用 API)
请注意,您可以 still access public data 而无需强制用户登录:
In the new Sheets API v4, there is no explicit declaration of visibility. API calls are made using spreadsheet IDs. If the application does not have permission to access specified spreadsheet, an error is returned. Otherwise the call proceeds.
请注意,您不需要将sheet发布到网络上。您需要做的就是确保 拥有 link 的任何人都可以访问 sheet.
(即当您在 Google 工作表 API 上单击 创建凭据 时,选择其他非 UI、用户数据,以及它说 "User data cannot be accessed from a platform without a UI because it requires user interaction for sign-in." 您可以安全地忽略该消息。API 密钥是您真正需要的,因为这是 public 数据。)
常见错误信息:
The request is missing a valid API key.
您没有在调用中包含 key=
参数。
API key not valid. Please pass a valid API key. Google developers console
您提供的 API 密钥不正确。确保您输入的密钥正确。如果您还没有密钥,请转到 Google developers console 并创建一个。
API Key not found. Please pass a valid API key.
Google developer console API key
您的 API 密钥可能是正确的,但您很可能没有添加 Google 表格权限。转到 Google 开发人员控制台 API 关键页面并添加 sheets 权限。
The caller does not have permission
您的 sheet 未设置为 public 仅可访问。
这是解决方案
- 在文档 url 中记下您的 sheet ID(不要使用已发布的 url 来查找 ID!)
- 发布您的 sheet,就像 html 页面一样
- 使用第 1 步中的 ID,
- 然后把它放在这个urlhttps://spreadsheets.google.com/feeds/cells/{id}/1/public/full?alt=json
/1 表示文档中的第一个 sheet