本指南包含将 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
参数相当于 v4 orderBys
字段,该字段接受 OrderBy 对象列表。
在 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 对象中返回报告数据,其中包含一组维度和一组 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 会返回布尔值字段 containsSampledData
,该字段设置为 true
。
对于抽样数据,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.\" }"
}
]
}
}