本指南包含将 Core Reporting API v3 迁移至 Analytics Reporting API v4 的步骤。
简介
为了充分利用 Analytics Reporting API v4 中引入的新功能,请迁移代码以使用这一 API。本指南显示了 Core Reporting API v3 中的请求和 Analytics Reporting API v4 中的请求的对应关系,以简化迁移工作。
Python 迁移
如果您是 Python 开发者,请使用 GitHub 上的 GAV4 助手库,将 Google Analytics(分析)Core Reporting API v3 请求转化为 Analytics Reporting API v4 请求。
端点
Core Reporting API v3 与 Analytics Reporting API v4 的端点和 HTTP 方法有所不同:
v3 端点
GET https://www.googleapis.com/analytics/v3/data/ga
v4 端点
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
以下示例比较了 v3 中的请求和 v4 中的等效请求:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&start-date=2015-11-01&end-date=2015-11-06 \
&metrics=ga:users&dimensions=ga:pagePath
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
"viewId":"XXXX",
"dateRanges":[
{
"startDate":"2015-11-01",
"endDate":"2015-11-06"
}],
"metrics":[
{
"expression":"ga:users"
}],
"dimensions": [
{
"name":"ga:pagePath"
}]
}]
}
客户端库和发现服务
如果您使用 Python、JavaScript 或其他建立在 Google Discovery Service 基础上的客户端库,您需要为 Reporting API v4 提供这一发现文档的位置。
Python
from apiclient import discovery
...
# Build the Analytics Reporting API v4 authorized service object.
analyticsReporting = discovery.build(
'analyticsreporting',
'v4',
http=http,
discoveryServiceUrl='https://analyticsreporting.googleapis.com/$discovery/rest')
JavaScript
gapi.client.load(
'https://analyticsreporting.googleapis.com/$discovery/rest',
'v4'
).then(...)
Java 和 PHP 客户端库是预建的,但您可以使用发现服务和 Google API 生成器生成这些库。
请求
API v4 参考详细说明了请求正文的结构。以下部分说明将 v3 请求参数迁移到 v4 请求参数的方法。
数据视图 ID
在 v3 中,用于接受“表格 ID”的 ids
参数格式为 ga:XXXX
,其中 XXXX
是数据视图(配置文件)ID。但在 v4 中,数据视图(配置文件)ID 要在请求正文中的 viewId
字段进行指定。
以下示例比较了 v3 请求中的 ids
参数以及 v4 请求中的 viewId
字段:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
"viewId":"XXXX",
...
}]
}
日期范围
Analytics Reporting API v4 可让您在一个请求中指定多个日期范围,并通过 dateRanges
字段获取 DateRange 对象的列表。在 v3 中,您可以使用 start-date
和 end-date
参数在请求中指定一个日期范围。
以下示例比较了 v3 请求中的 start-date
和 end-date
参数以及 v4 请求中的 dateRanges
字段:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&start-date=2015-11-01&end-date=2015-11-06 \
...
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
"viewId":"XXXX",
"dateRanges":[
{
"startDate":"2015-11-01",
"endDate":"2015-11-06"
}],
....
}]
}
指标
v3 metrics
参数对应于获取 Metric 对象列表的 v4 metrics
字段。
以下示例比较了 v3 请求中的 metrics
参数和 v4 请求中的 metrics
字段:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&start-date=2015-11-01&end-date=2015-11-06 \
&metrics=ga:users,ga:sessions \
...
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
"viewId":"XXXX",
"dateRanges":[
{
"startDate":"2015-11-01",
"endDate":"2015-11-06"
}],
"metrics":[
{
"expression":"ga:users"
},{
"expression":"ga:sessions"
}],
...
}]
}
维度
v3 dimensions
参数对应于获取 Dimension 对象列表的 v4 dimensions
字段。
以下示例比较了 v3 请求中的 dimensions
参数以及 v4 请求中的 dimensions
字段:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&dimensions=ga:country,ga:browser&... \
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
...
"dimensions": [
{
"name":"ga:country"
},{
"name":"ga:browser"
}],
...
}]
}
排序
v3 sort
参数等效于获取 OrderBy 对象列表的 v4 orderBys
字段。
在 v4 中,要按照维度或指标值对结果排序:
以下示例比较了 v3 请求中的 sort
参数和 v4 请求中的 orderBy
字段;它们均以降序对用户进行排序,按照字母顺序对来源进行排序:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&sort=-ga:users,ga:source
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
...
"orderBys": [
{
"fieldName": "ga:users",
"sortOrder": "DESCENDING"
},{
"fieldName": "ga:source"
}],
}]
}
抽样级别
v3 samplingLevel
参数对应于 v4 samplingLevel
字段。在 v3 中,接受的 samplingLevel
值是 FASTER
、HIGHER_PRECISION
和 DEFAULT
;在 v4 中,接受的 samplingLevel
值是 SMALL
、LARGE
和 DEFAULT
。注意 v3 中的 FASTER
在 v4 中已更改为 SMALL
,HIGHER_PRECISION
更改为 LARGE
。
以下示例比较了 v3 请求中的 samplingLevel
参数以及 v4 请求中的 samplingLevel
字段:
v3
https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX ...\
samplingLevel=HIGHER_PRECISION
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
...
"samplingLevel": "LARGE"
}]
}
细分
v3 segment
参数对应于获取 Segment 对象列表的 v4 segments
字段。
细分 ID
在 v4 中,要按照细分 ID 请求细分,请构建一个 Segment 对象,并通过 segmentId 字段提供其 ID。
以下示例比较了 v3 请求中的 segment
参数以及 v4 请求中的 segments
字段:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=gaid::-11
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests": [{
...
"viewId": "XXXX",
"segments": [{
"segmentId": "gaid::-11"
}]
}]
}
动态细分
在 v4 中,为表达更复杂的细分定义,请使用包含 DynamicSegment 对象的 segments
字段。
以下示例比较了 v3 请求中的 segment
参数以及 v4 请求中包含 DynamicSegment
对象的 segments
字段:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=sessions::condition::ga:medium==referral
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests": [{
...
"segments": [{
"dynamicSegment": {
"name": "segment_name",
"sessionSegment": {
"segmentFilters": [{
"simpleSegment": {
"orFiltersForSegment": [{
"segmentFilterClauses": [{
"dimensionFilter": {
"dimensionName": "ga:medium",
"operator": "EXACT",
"expressions": [ "referral" ]
}
}]
}]
}
}]
}
}
}]
}]
}
您可以在细分中结合使用条件和顺序:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=users::condition::ga:revenue>10;sequence::ga:deviceCategory==desktop->>ga:deviceCategory==mobile
v4
"reportRequests": [{
"dateRanges": [
{ "endDate": "2014-11-30", "startDate": "2014-11-01" }
],
"metrics": [
{"expression": "ga:pageviews"},
{"expression": "ga:sessions"}
],
"viewId": "XXXX",
"dimensions":[{"name":"ga:medium"}, {"name":"ga:segment"}],
"segments": [{
"dynamicSegment": {
"name": "segment_name",
"userSegment": {
"segmentFilters": [{
"simpleSegment": {
"orFiltersForSegment": [{
"segmentFilterClauses": [{
"metricFilter": {
"metricName": "ga:sessions",
"operator": "GREATER_THAN",
"comparisonValue": "10"
}
}]
}]
}
},
{
"sequenceSegment": {
"segmentSequenceSteps": [{
"orFiltersForSegment": [{
"segmentFilterClauses": [{
"dimensionFilter": {
"dimensionName": "ga:deviceCategory",
"operator": "EXACT",
"expressions": ["desktop"]
}
}]
}],
"matchType": "PRECEDES"
},{
"orFiltersForSegment": [{
"segmentFilterClauses": [{
"dimensionFilter": {
"dimensionName": "ga:deviceCategory",
"operator": "EXACT",
"expressions": ["mobile"]
}
}]
}]
}]
}
}]
}
}
}]
}]
v4 中的 v3 细分语法
v4 API 中的 segmentId 字段支持 v3 API 中的细分语法。
以下示例说明 v4 等效请求中的 segmentId
字段如何支持 v3 请求中的 segment
参数:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=sessions::condition::ga:medium==referral
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests": [{
...
"viewId": "XXXX",
"segments": [{
"segmentId": "sessions::condition::ga:medium==referral"
}]
}]
}
过滤器
v4 使用 dimensionFilterClauses
过滤维度,使用 metricFilterClauses
过滤指标。dimensionFilterClauses
包含 DimensionFilter 对象列表;metricFilterClauses
包含 MetricFilter 对象列表。
以下示例比较了 v3 请求中的 filters
参数以及 v4 请求中的 dimensionFilterClauses
字段:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&start-date=2015-06-01&end-date=2015-07-31&metrics=ga:users& \
dimensions=ga:browser&filters=ga:browser==Firefox
v4
"reportRequests": [{
"dateRanges": [
{ "endDate": "2014-11-30", "startDate": "2014-11-01" }
],
"metrics": [
{"expression": "ga:pageviews"},
{"expression": "ga:sessions"}
],
"viewId": "XXXX",
"dimensions":[{"name":"ga:browser"}, {"name":"ga:country"}],
"dimensionFilterClauses": [{
"filters": [{
"dimension_name": "ga:browser",
"operator": "EXACT",
"expressions": ["Firefox"]
}]
}]
}]
v4 中的 v3 过滤器语法
虽然 v4 中的 filtersExpression 字段支持 v3 中的 filters
语法,还是请使用 dimensionFilterClauses
和 metricFilterClauses
过滤维度和指标。
以下示例说明 v4 等效请求中的 filtersExpression
字段如何支持 v3 请求中的 filters
参数:
v3
GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga%XXXX \
&filters=ga:browser==Firefox
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests": [{
...
"filtersExpression": "ga:browser==Firefox"
}]
}
空行
v3 include-empty-rows
参数对应于 v4 中的 includeEmptyRows
字段。v3 参数默认值为 true,而在 v4 中该字段默认值为 false。如果您没有在 v3 中设置该值,则需要在 v4 中将该值设置为 true。
以下示例比较了 v3 请求中的 include-empty-rows
参数以及 v4 请求中的 includeEmptyRows
字段:
v3
https://www.googleapis.com/analytics/v3/data/ga? ...\
&include-empty-rows=true
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
...
"includeEmptyRows": "true",
}]
}
分页
v4 使用 pageToken
和 pageSize
字段对大量结果进行分页。而 pageToken
取自响应对象的 nextPageToken
属性。
以下示例比较了 v3 请求中的 start-index
及 max-results
参数和 v4 请求中的 pageToken
及 pageSize
字段:
v3
https://www.googleapis.com/analytics/v3/data/ga? ...\
&start-index=10001&max-results=10000
v4
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":[
{
...
# Taken from `nextPageToken` of a previous response.
"pageToken": "10000",
"pageSize": "10000",
}]
}
标准参数
Analytics Reporting API v4 支持 v3 API 中的大部分标准查询参数,但不支持 userIp
和 callback
参数。
以下示例比较了 v3 请求和 v4 请求中的 quotaUser
参数:
v3 端点
GET https://www.googleapis.com/analytics/v3/data/ga?quotaUser=1X3F2F2
v4 端点
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet?quotaUser=1X3F2F2
响应
由于 v4 允许在一个 HTTP 请求中提交多个 ReportRequest 对象,您可以在响应中获得一组报告对象。对于提交的每个 ReportRequest,您可以在响应中获得相应的报告。
报告
v4 报告中有三个顶级字段:columnHeader
、data
和 nextPageToken
。
由于 v4 响应正文不包含对所有查询参数的响应,这与 v3 响应不同,要获得对特定查询参数的响应,客户端应用必须将该参数添加到 ReportRequest。
我们已经在分页一节中说明了 nextPageToken
,因此先了解一下 columnHeader 对象。
列标题
列标题包含一列已命名维度和一个 MetricHeader 对象,后者包含一列 MetricHeaderEntry 对象。每个 MetricHeaderEntry 对象指定指标 name
及其 type
(币种、百分比等等),用于确定输出结果的格式。
以下示例比较了 v3 响应中的 columnHeaders
字段以及 v4 响应中的 columnHeader
字段:
v3
"columnHeaders": [
{
"name":"ga:source",
"columnType":"DIMENSION",
"dataType":"STRING"
},{
"name":"ga:city",
"columnType":"DIMENSION",
"dataType":"STRING"
},{
"name":"ga:sessions",
"columnType":"METRIC",
"dataType":"INTEGER"
},{
"name":"ga:pageviews",
"columnType":
"METRIC",
"dataType":"INTEGER"
}
]
v4
"columnHeader": {
"dimensions": [
"ga:source",
"ga:city"
],
"metricHeader": {
"metricHeaderEntries": [
{
"name": "ga:pageviews",
"type": "INTEGER"
},
{
"name": "ga:sessions",
"type": "INTEGER"
}
]
}
},
报告行
Core Reporting API v3 在 rows 数组中返回报告数据,其中包括请求的维度和指标。
Analytics Reporting API v4 在 ReportRow 对象中返回报告数据,其中包含一组 dimensions 和一组 DateRangeValues 对象,每个数组包含一个或两个日期范围,如下图所示:
行
v3
"rows": [
[
"google",
"Philadelphia",
"60",
"5"
],
[
"google",
"Johnstown",
"21",
"1"
],
[
"google",
"Progress",
"7",
"1"
]
],
v4
"rows": [
{
"dimensions": [
"google",
"Philadelphia"
],
"metrics": [
{
"values": [
"60",
"5"
]
}
]
},
{
"dimensions": [
"google",
"Johnstown"
],
"metrics": [
{
"values": [
"21",
"1"
]
}
]
},
{
"dimensions": [
"google",
"Progress"
],
"metrics": [
{
"values": [
"7",
"1"
]
}
]
}
],
抽样数据
如果对结果进行了抽样,则 Core Reporting API v3 会返回值为 true
的布尔型字段 containsSampledData
。
但如果是对数据进行了抽样,那么 Analytics Reporting API v4 不会返回布尔值,而是返回 samplesReadCounts
和 samplingSpaceSizes
字段。如果未对结果进行抽样,将不会定义这些字段。以下 Python 示例显示了在报告包含抽样数据的情况下应如何进行计算:
def ContainsSampledData(report):
"""Determines if the report contains sampled data.
Args:
report (Report): An Analytics Reporting API v4 response report.
Returns:
bool: True if the report contains sampled data.
"""
report_data = report.get('data', {})
sample_sizes = report_data.get('samplesReadCounts', [])
sample_spaces = report_data.get('samplingSpaceSizes', [])
if sample_sizes and sample_spaces:
return True
else:
return False
下例中的响应所包含的抽样数据来自有两个日期范围的请求。这些结果计算自约 1500 万个会话的抽样空间中的约 50 万个样本:
{
"reports":
[
{
"columnHeader": {
...
},
"data": {
...
"samplesReadCounts": [ "499630","499630"],
"samplingSpaceSizes": ["15328013","15328013"],
}
}
]
}
解析 v4 响应
以下示例代码解析和输出 Analytics Reporting API v4 响应:
Python
def printResponse(self, response):
"""Parses and prints the Analytics Reporting API v4 response"""
for report in response.get('reports', []):
columnHeader = report.get('columnHeader', {})
dimensionHeaders = columnHeader.get('dimensions', [])
metricHeaders = columnHeader.get('metricHeader', {}).get('metricHeaderEntries', [])
rows = report.get('data', {}).get('rows', [])
for row in rows:
dimensions = row.get('dimensions', [])
dateRangeValues = row.get('metrics', [])
for header, dimension in zip(dimensionHeaders, dimensions):
print header + ': ' + dimension
for i, values in enumerate(dateRangeValues):
print 'Date range (' + str(i) + ')'
for metricHeader, value in zip(metricHeaders, values.get('values')):
print metricHeader.get('name') + ': ' + value
Java
public static void printResponse(GetReportsResponse response) {
for (Report report: response.getReports()) {
ColumnHeader header = report.getColumnHeader();
List<String> dimensionHeaders = header.getDimensions();
List<MetricHeaderEntry> metricHeaders = header.getMetricHeader().getMetricHeaderEntries();
List<ReportRow> rows = report.getData().getRows();
for (ReportRow row: rows) {
List<String> dimensions = row.getDimensions();
List<DateRangeValues> metrics = row.getMetrics();
for (int i = 0; i < dimensionHeaders.size() && i < dimensions.size(); i++) {
System.out.println(dimensionHeaders.get(i) + ": " + dimensions.get(i));
}
for (int j = 0; j < metrics.size(); j++) {
System.out.print("Date Range (" + j + "): ");
DateRangeValues values = metrics.get(j);
for (int k = 0; k < values.size() && k < metricHeaders.size(); k++) {
System.out.println(metricHeaders.get(k).getName() + ": " + values.get(k));
}
}
}
}
}
错误处理
因为 v4 中的错误响应格式与 v3 中的错误响应格式不同,请更新您的代码以处理 v4 错误响应。
以下示例比较 v3 中的错误响应和 v4 中的等效错误响应:
v3
{
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "User does not have sufficient permissions for this profile.",
}
],
"code": 403,
"message": "User does not have sufficient permissions for this profile."
}
}
v4
{
"error": {
"code": 403,
"message": "User does not have sufficient permissions for this profile.",
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.DebugInfo",
"detail": "[ORIGINAL ERROR] generic::permission_denied: User does not have sufficient permissions for this profile. [google.rpc.error_details_ext] { message: \"User does not have sufficient permissions for this profile.\" }"
}
]
}
}