我正在查询谷歌广告api,并需要保存为json的结果。将GoogleAdsRow类型转换为json的最好方法是什么?
google ads的结果如下所示(活动和客户ids是假的):
campaign {
resource_name: "customers/752830100/campaigns/22837002"
id {
value: 22837002
}
name {
value: "test"
}
}
metrics {
clicks {
value: 51
}
impressions {
value: 33
}
}类型= <class 'google.ads.googleads_v1.types.GoogleAdsRow'>
发布于 2020-12-03 19:58:20
Google.protobuf有一个名为json_format的方法,可以做到这一点。下面是一个代码示例来帮助您:
# Import the method
from google.protobuf import json_format
import json
# Query the Ads API,
ga_service = client.get_service('GoogleAdsService', version='YOUR_VERSION')
query = ('YOUR_QUERY')
# Response as an iterator made up of GoogleAdsRow
response = ga_service.search(customer_id, query)
# Converting each of the GoogleAdsRow to json
for row in response :
json_str = json_format.MessageToJson(row)
d = json.loads(json_str)发布于 2019-06-10 21:20:14
现在我也在寻找同样的问题。我发现的一个解决方法是在json.dumps中使用CustomEncoder。下面是一个示例:
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (google.protobuf.wrappers_pb2.StringValue,
google.protobuf.wrappers_pb2.Int64Value,
google.protobuf.wrappers_pb2.DoubleValue)):
return obj.value
elif isinstance(obj, google.protobuf.pyext._message.RepeatedCompositeContainer):
data = []
try:
while True:
item = obj.pop()
data.append(self.default(item))
except IndexError:
return data
elif isinstance(obj, google.ads.google_ads.v1.proto.common.custom_parameter_pb2.CustomParameter):
return {
self.default(obj.key): self.default(obj.value)
}
return json.JSONEncoder.default(self, obj)在json.dumps(data, cls=CustomEncoder)中使用上述编码器
这是我到目前为止唯一的解决方案。如果我找到更好的解决方案,我会更新它。
编辑:找到解决方案。下面是New Encoder类。
class GoogleProtoEncoder(json.JSONEncoder):
"""
Custom JSON Encoder for GoogleAdsRow.
Usage: json.dumps(data, cls=GoogleProtoEncoder)
"""
def default(self, obj):
"""
Overriden method. When json.dumps() is called, it actually calls this method if
this class is specified as the encoder in json.dumps().
"""
if isinstance(obj, google.protobuf.message.Message) and hasattr(obj, 'value'):
# This covers native data types such as string, int, float etc
return obj.value
elif isinstance(obj, google.protobuf.pyext._message.RepeatedCompositeContainer):
# This is basically for python list and tuples
data = []
try:
while True:
item = obj.pop()
data.append(self.default(item))
except IndexError:
return data
elif isinstance(obj, google.ads.google_ads.v1.proto.common.custom_parameter_pb2.CustomParameter):
# Equivalent to python dictionary
return {
self.default(obj.key): self.default(obj.value)
}
elif isinstance(obj, google.protobuf.message.Message):
# All the other wrapper objects which can have different fields.
return {key[0].name: getattr(obj, key[0].name) for key in obj.ListFields()}
return json.JSONEncoder.default(self, obj)谢谢。
编辑:更新解决方案。在V7中工作
import proto
response = ga_service.search_stream(search_request)
for batch in response:
for row in batch.results:
logging.debug(proto.Message.to_dict(row))发布于 2020-07-01 20:51:06
如果您不需要使用SDK,另一个获取json的选择是查询直接发送post请求的API,这将返回一个json响应:
r = requests.post('https://googleads.googleapis.com/v3/customers/YOUR_CUSTOMER_ID/googleAds:searchStream',
headers={'Authorization': f'Bearer {access_token}',
'developer-token' : developer_token,
'login-customer-id' : 'YOUR_CUSTOMER_ID',
'Content-Type': 'application/json'},
params={"query" : query})https://stackoverflow.com/questions/55458027
复制相似问题