使用 c网址 与 Google 数据服务进行交互

警告:本页面介绍的是 Google 的旧版 API,即 Google 数据 API;它仅与 Google 数据 API 目录中列出的许多 API 相关,其中许多 API 已替换为较新的 API。如需了解特定新 API,请参阅新 API 的文档。如需了解如何使用较新的 API 向请求授权,请参阅 Google 帐号身份验证和授权

Ryan Boyd,Google 数据 API 团队
2007 年 9 月

简介

本质上,Google 数据 API 使用 Atom Feed 和条目 (XML) 作为数据格式,并使用 HTTP 作为数据传输协议 - 扩展 Atom 发布协议。为了更轻松地与 Google Data API 进行交互,我们发布了很多客户端库。不过,我们随时欢迎使用较低级别的工具来使用我们的服务,只需一点指导即可轻松启用。

c网址 是一个命令行应用,用于使用各种协议(包括 HTTP)执行请求。开发者通常使用 c网址 来测试 Google 数据服务,因为它支持在低级别与 API 进行交互所需的 HTTP 功能。

c网址 仅支持执行 HTTP 通信,因此了解 Google 数据协议、服务专用协议和使用的 XML 数据格式是使用这些应用的先决条件。本文中提及了一些其他工具,以便您更轻松地完成这些任务。

本文会使用基于 Picasa 线上影集数据 API 的示例。不过,所有这些示例都可以轻松应用到其他 Google 数据 API

获取并安装 c网址

c网址 通常在许多 UNIX/Linux 平台的默认安装版中提供。尝试在您最喜爱的 shell 中输入 curl,即可查看该工具是否已安装且位于您的 PATH 中。如果您未安装该工具,请访问 c网址 网站上的下载页面,以获取官方源代码或用户提供的二进制软件包。请注意,命令行工具使用 libcurl 库,该库可作为单独的下载包提供,因此,如果您不打算从源代码进行编译,请务必下载“binary”软件包,而不是“libcurl”软件包。如果您希望使用 c网址 获取身份验证令牌或访问某些需要使用 SSL 发出请求的 Google 数据服务,则必须启用支持 SSL 的软件包。

向 Google 数据服务进行身份验证

经过身份验证的 Google 数据请求是通过在请求中添加 HTTP 标头(包含 StreetView(桌面/移动应用)或 AuthSub(Web 应用)身份验证令牌来执行的。使用 c网址 进行测试时,虽然 SRA 是更简单的方法,但下文对此进行了记录。AuthSub 身份验证标头可与 c网址 配合使用,但更高级的获取令牌的过程不在本文的讨论范围内。

使用 Paging

StreetView 适用于安装(桌面/移动)的应用。通过这种身份验证方法,使用 Google 数据 API 的应用程序会直接处理用户的用户名和密码。

Paging 的身份验证请求会将用户名、密码和服务名称作为表单发布变量。这些变量分别作为 EmailPasswdservice 参数传递。此请求会生成包含多个令牌的响应,这些令牌可用于向 Google 数据服务发出请求。请注意,通过 curl 传递的数据参数如果包含非 ASCII 字符(通常出现在 EmailPasswd 参数中),则必须进行网址编码。您可以要求 curl 使用 --data-urlencode 标志对这些参数进行网址编码。

请求示例:

curl https://www.google.com/accounts/ClientLogin \
--data-urlencode Email=brad.gushue@example.com --data-urlencode Passwd=new+foundland \
-d accountType=GOOGLE \
-d source=Google-cURL-Example \
-d service=lh2

回应示例:

SID=DQAAAHYBADCv2pSv7nflacDNwz3zEDUGtrSvNVDcpkSfddi77b3U5sEaHmP8YLWhmA36F9rk85mL8J5dqo4apn0T1vKz0fPGI9Xtnuet6cuE2ZzYvrNIwbSC_HjTqF4zudNQnnlDuD2wqZT-g1qXI8KhGAQZV4NexHZoQPlabTsGuRZeIBxj1A
LSID=EUBBBIaBADCl-kNxvRVmcQghpt3cqSMfEooKR9flLOUZqwgP9OrZS83gse-KSdTNeXhxsET7FYenDhceP9lIPOmesH-t9qh-AWUHjjMdZEbUNeF9mWyzln6Z-FajaiG-cVFkqW0ZJ8ZbnCP30xXj6xFK6QxaAcqy_9Pej8jhEnxS9E61ftQGPg
Auth=EUBBIacAAADK-kNxvRVmcQghpt3cqSMfEooLNMflLNIQqwgP9OrZS83gs-KSdTNeXhxsET7FYePWmaD8Vsy1V4LSUGMUP48Je2TO8OcjBj6HgAtPhiZeX-gKDfagZDK44j4n-Tkb44nhOnp2_QPSnBj3Z2vYwOEDjjG3Q53aQVC2132JKOuGh

如需了解有关上述请求中使用的参数的具体信息,请参阅 Paging 文档。在此示例中,我们使用的服务是 Picasa 线上影集数据 API。服务名称 (service) 为 lh2。您可以在 Google 数据 API 常见问题解答页面中找到其他 Google 数据服务的服务名称。

以上响应中 Auth 令牌的值是向 Google 数据服务进行身份验证的唯一值。此令牌的值会形成 HTTP 标头,然后将标头用于对 Google 数据服务的每个请求。

curl --silent --header "Authorization: GoogleLogin auth=EUBBIacAAADK\
-kNxvRVmcQghpt3cqSMfEooLNMflLNIQqwgP9OrZS83gs-KSdTNeXhxs\
ET7FYePWmaD8Vsy1V4LSUGMUP48Je2TO8OcjBj6HgAtPhiZeX-gKDfag\
ZDK44j4n-Tkb44nhOnp2_QPSnBj3Z2vYwOEDjjG3Q53aQVC2132JKOuGh" \
"http://picasaweb.google.com/data/feed/api/user/default"

注意:以上命令中用换行符(“ ”)转义的换行符的方法不适用于 Windows 命令 shell,因此如果您在 Windows 上运行 curl,就必须在一行中输入整个命令。


检索 Feed 和条目

在 Google Data API 中,可通过使用一个可选查询参数集对网址执行 HTTP GET 来检索 Feed 和条目。由于我们要执行 GET 请求,因此只需要将身份验证标头和网址传递给 curl。以下示例将继续使用 Picasa 线上影集数据 API,并用于检索经过身份验证的用户拥有的影集列表。请注意,在此示例中,我们已将身份验证令牌缩短为 ABCDEFG,但应该使用完整令牌(例如,上面的 EUBBIacA...32JKOuGh)。

curl --silent --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/feed/api/user/default"

这将返回一个无格式的 XML blob:

<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:geo='http://www.w3.org/2003/01/geo/wgs84_pos#' xmlns:gml='http://www.opengis.net/gml' xmlns:georss='http://www.georss.org/georss' xmlns:photo='http://www.pheed.com/pheed/' xmlns:media='http://search.yahoo.com/mrss/' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gphoto='http://schemas.google.com/photos/2007'><id>http://picasaweb.google.com/data/feed/base/user/brad.gushue</id><updated>2007-09-13T21:30:21.454Z</updated>...</entry></feed>

有一些不错的工具可用于设置此输出的格式,使其更易于用户理解,其中包括 tidy。使用 tidy 的最简单方法是将 curl 命令的输出传送到 tidy,如下所示:

curl --silent --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/feed/api/user/default" | tidy -xml -indent -quiet

这样可以生成更易读的 Feed,如下所示:

<?xml version='1.0' encoding='utf-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' 
xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' 
xmlns:geo='http://www.w3.org/2003/01/geo/wgs84_pos#' 
xmlns:gml='http://www.opengis.net/gml' 
xmlns:georss='http://www.georss.org/georss' 
xmlns:photo='http://www.pheed.com/pheed/' 
xmlns:media='http://search.yahoo.com/mrss/' 
xmlns:batch='http://schemas.google.com/gdata/batch' 
xmlns:gphoto='http://schemas.google.com/photos/2007'>
  <id>http://picasaweb.google.com/data/feed/api/user/brad.gushue</id>
  <updated>2007-09-13T21:47:07.337Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
  term='http://schemas.google.com/photos/2007#user' />
  <title type='text'>brad.gushue</title>
  <subtitle type='text'></subtitle>
  <icon>
  http://lh6.google.com/brad.gushue/AAAAj9zigp4/AAAAAAAAAAA/RiMAlXV4MFI/s64-c/brad.gushue</icon>
  <link rel='http://schemas.google.com/g/2005#feed'
  type='application/atom+xml'
  href='http://picasaweb.google.com/data/feed/api/user/brad.gushue' />
  <link rel='alternate' type='text/html'
  href='http://picasaweb.google.com/brad.gushue' />
  <link rel='self' type='application/atom+xml'
  href='http://picasaweb.google.com/data/feed/api/user/brad.gushue?start-index=1&max-results=1000' />
  <author>
    <name>Brad</name>
    <uri>http://picasaweb.google.com/brad.gushue</uri>
  </author>
  <generator version='1.00' uri='http://picasaweb.google.com/'>
  Picasaweb</generator>
  <openSearch:totalResults>8</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>1000</openSearch:itemsPerPage>
  <gphoto:user>brad.gushue</gphoto:user>
  <gphoto:nickname>Brad</gphoto:nickname>
  <gphoto:thumbnail>
  http://lh6.google.com/brad.gushue/AAAAj9zigp4/AAAAAAAAAAA/RiMAlXV4MFI/s64-c/brad.gushue</gphoto:thumbnail>
  <entry>
    <id>
    http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389720904593</id>
    <published>2007-05-23T04:55:52.000Z</published>
    <updated>2007-05-23T04:55:52.000Z</updated>
    <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/photos/2007#album' />
    <title type='text'>Trip To Italy</title>
    <summary type='text'>This was the recent trip I took to
    Italy.</summary>
    <rights type='text'>public</rights>
    <link rel='http://schemas.google.com/g/2005#feed'
    type='application/atom+xml'
    href='http://picasaweb.google.com/data/feed/api/user/brad.gushue/albumid/9810315389720904593' />
    <link rel='alternate' type='text/html'
    href='http://picasaweb.google.com/brad.gushue/TripToItalyV2' />
    <link rel='self' type='application/atom+xml'
    href='http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389720904593' />
    <link rel='edit' type='application/atom+xml'
    href='http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389720904593/123456' />
    <author>
      <name>Brad</name>
      <uri>http://picasaweb.google.com/brad.gushue</uri>
    </author>
    <gphoto:id>9810315389720904593</gphoto:id>
    <media:group>
    ...
    </media:group>
  </entry>
  <entry>
  ...
  </entry>

</feed>

与提供 Feed 网址不同的是,您可以通过提供条目的网址来检索各个条目,从而达到相同的效果。

更新条目

如要更新 Google Data API 中的条目,请在请求的正文中使用新条目的 XML 副本对修改网址执行 HTTP PUT

  1. 使用 atom:link/@rel='self' 网址值检索条目
  2. 在本地更新条目以进行所需的更改
  3. 使用 atom:link/@rel='edit' 网址值将条目 PUT 返回给服务器

1. 检索条目

可以使用上述 Feed 代码块中以粗体显示的两个网址之一来检索条目。所需网址是带有 rel='self'link 元素的 href 值。

curl --silent --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389720904593"

2. 在本地更新条目

检索该条目后,您需要使用本地文本编辑器或应用对其进行更新,以便对该条目进行必要的更改。在上述命令中检索条目时,我们并没有像前面的示例那样将结果传输至 tidy。结果是 XML 表示相同的数据,但格式与传送至 tidy 的版本不同。如需手动修改条目,使用 tidy 通常可以更轻松地处理 XML。

注意:请务必在发布新条目时添加所有用作 atom:entry 属性的 XML 命名空间定义。省略这些属性会导致解析异常。此外,tidy 会将换行符定义之间的空格替换为换行符。虽然这是有效的 XML,但 Google 数据服务目前不接受它。如果您使用的是 tidy,请务必在 entry 元素中的这些属性之间添加额外的空格。

3. 更新服务器上的条目

使用 edit 网址,您需要使用 c网址 将条目的副本 PUT 到服务中。一个标头,用于指明要添加到服务器的内容的类型。以下代码段假定包含更新后的条目的文件保存在 updated_entry.xml 中。

curl --silent --data-binary "@updated_entry.xml" --request PUT --header "Content-Type: application/atom+xml" --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389720904593/123456"

创建条目

Google Data API 中的条目是使用新条目对帖子网址执行 HTTP POST 来创建的。atom:id 由服务器分配,因此无需包含在新条目中。创建新条目的最简单方法是采用旧条目并进行修改。以下示例将执行此操作。

  1. 使用 atom:link/@rel='self' 检索模板条目
  2. 在本地修改模板条目以移除不必要的信息,并进行必要的更改
  3. 使用 Feed 的 post 网址将条目 POST 返回给服务器。您可以在所检索 Feed 中通过 rel='http://schemas.google.com/g/2005#post' 找到 link 元素的 href 值,或者在 http://code.google.com 上的服务文档中找到该网址。

1. 检索模板条目

可以使用 rel='self'link 元素的 href 值检索单个条目,检索方式与在上述示例中更新条目前一样。

curl --silent --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389720904593" | tidy -xml -indent -quiet > template_entry.xml

使用 tidy 后,响应将如下所示:

<entry xmlns='http://www.w3.org/2005/Atom' 
xmlns:exif='http://schemas.google.com/photos/exif/2007'
xmlns:geo='http://www.w3.org/2003/01/geo/wgs84_pos#'
xmlns:gml='http://www.opengis.net/gml'
xmlns:georss='http://www.georss.org/georss'
xmlns:photo='http://www.pheed.com/pheed/'
xmlns:media='http://search.yahoo.com/mrss/'
xmlns:batch='http://schemas.google.com/gdata/batch'
xmlns:gphoto='http://schemas.google.com/photos/2007'>
  <id>
  http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389741123981</id>
  <published>2007-05-23T04:55:52.000Z</published>
  <updated>2007-05-23T04:55:52.000Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
  term='http://schemas.google.com/photos/2007#album' />
  <title type='text'>Trip To Italy</title>
  <summary type='text'>This was the recent trip I took to
  Italy.</summary>
  <rights type='text'>public</rights>
  <link rel='http://schemas.google.com/g/2005#feed'
  type='application/atom+xml'
  href='http://picasaweb.google.com/data/feed/api/user/brad.gushue/albumid/9810315389741123981' />
  <link rel='alternate' type='text/html'
  href='http://picasaweb.google.com/brad.gushue/TripToItaly' />
  <link rel='self' type='application/atom+xml'
  href='http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389741123981' />
  <link rel='edit' type='application/atom+xml'
  href='http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389741123981/1179896152905401' />
  <author>
    <name>Brad</name>
    <uri>http://picasaweb.google.com/brad.gushue</uri>
  </author>
  <gphoto:id>9810315389741123981</gphoto:id>
  <gphoto:name>TripToItaly</gphoto:name>
  <gphoto:location></gphoto:location>
  <gphoto:access>public</gphoto:access>
  <gphoto:timestamp>1179896152000</gphoto:timestamp>
  <gphoto:numphotos>0</gphoto:numphotos>
  <gphoto:numphotosremaining>500</gphoto:numphotosremaining>
  <gphoto:bytesUsed>0</gphoto:bytesUsed>
  <gphoto:user>brad.gushue</gphoto:user>
  <gphoto:nickname>Brad</gphoto:nickname>
  <gphoto:commentingEnabled>true</gphoto:commentingEnabled>
  <gphoto:commentCount>0</gphoto:commentCount>
  <media:group>
    <media:title type='plain'>Trip To Italy</media:title>
    <media:description type='plain'>This was the recent trip I took
    to Italy.</media:description>
    <media:keywords></media:keywords>
    <media:content url='http://lh5.google.com/brad.gushue/ADFUFKqeA5E/AAAAAAAAABc/V6Sga_Z03WU/TripToItaly.jpg'
    type='image/jpeg' medium='image' />
    <media:thumbnail url='http://lh5.google.com/brad.gushue/ADFUFKqeA5E/AAAAAAAAABc/V6Sga_Z03WU/s160-c/TripToItaly.jpg'
    height='160' width='160' />
    <media:credit>Brad</media:credit>
  </media:group>

</entry>

2. 修改模板条目

我们想利用近期的冰壶比赛图片创建一个名为“加拿大曲棍球”的影集。Google 数据允许您删除服务器为其提供的值的 Atom 元素,因此为了创建这个简单的模板条目,我们将移除 atom:idatom:publishedatom:updatedatom:author 以及 Feed 中的各种 atom:link 元素。这将获得一个简化的模板条目。然后需要修改该条目,以表示我们正在创建的新影集:

<entry xmlns='http://www.w3.org/2005/Atom' 
xmlns:gphoto='http://schemas.google.com/photos/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
  term='http://schemas.google.com/photos/2007#album' />
  <title type='text'>Curling in Canada</title>
  <summary type='text'>Pictures of all my curling matches in Canada.</summary>
  <gphoto:location>Canada</gphoto:location>
  <gphoto:access>public</gphoto:access>
  <gphoto:commentingEnabled>true</gphoto:commentingEnabled>

</entry>

注意:请务必在发布新条目时添加所有用作 atom:entry 属性的 XML 命名空间定义。省略这些属性会导致解析异常。此外,tidy 将替换命名空间定义之间的空格,并将其替换为换行符。虽然这是有效的 XML,但 Google 数据服务目前不接受它。如果您使用的是 tidy,请务必在 entry 元素中的这些属性之间添加额外的空格。

3. 将新条目发布到服务器

curl 命令用于将新条目发布到服务器,这与更新现有条目非常相似,不同的是网址不同:

curl --silent --request POST --data-binary "@template_entry.xml" --header "Content-Type: application/atom+xml" --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/feed/api/user/brad.gushue" | tidy -xml -indent -quiet

如果发布成功,则生成的 XML 输出是新创建的条目的副本。此条目将包括创建条目时服务器生成的内容,包括 atom:idatom:publishedatom:updatedatom:link 元素的值。如果在此期间未进行任何额外更改,则生成的 link 值可用于修改或删除条目。

删除条目

删除条目与更新条目十分类似,只不过使用的是 HTTP DELETE 方法(而不是 HTTP PUT),并且无需发送任何数据。与更新请求一样,edit 网址也用作 HTTP 请求的目标。

curl --silent --request DELETE --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/entry/api/user/brad.gushue/albumid/9810315389720904593/123456"

上传媒体对象

Picasa 线上影集数据 API 和文档列表数据 API 的一项重要功能是能够上传二进制对象。c网址 可以轻松完成上传二进制数据和 Slug 标头。不过,Documents List 数据 API 目前需要将 XML 与二进制数据一起发布为 MIME 多部分消息。本文无法介绍如何构建多部分消息。

以下示例展示了如何将名为 sweeping_the_rock.png 的图片上传到标题为“Seeping the Rock”的 Picasa 线上影集中:

curl --silent --request POST --data-binary "@sweeping_the_rock.png" --header "Slug: Sweeping the rock" --header "Content-Type: image/png" --header "Authorization: GoogleLogin auth=ABCDEFG" "http://picasaweb.google.com/data/feed/api/user/brad.gushue/albumid/5113621341847124417" | tidy -xml -indent -quiet

其他命令行工具

一些开发者更喜欢使用其他命令行工具进行学习或调试。

常用工具包括:

  • telnet, openssl 用于与网络服务器建立原始套接字连接(分别为基于纯文本和 SSL),并且可用于与 Google 数据服务交互。请注意,并非所有 Google 数据服务都支持 SSL。打开连接的方法如下:
    • telnet picasaweb.google.com 80(Picasa 线上影集数据 API)
    • openssl s_client -connect www.google.com:443(www.google.com 上的 Google 日历数据 API 和其他服务)
    建立连接后,必须发送原始 HTTP 请求。此请求包括 HTTP 动词、相对路径、版本、所有标头和请求正文。下面是一个示例:
    POST /data/feed/api/user/brad.gushue HTTP/1.1
    Host: picasaweb.google.com
    Authorization: GoogleLogin auth=ABCDEFG
    Content-Length: 493
    
    <entry xmlns='http://www.w3.org/2005/Atom' 
    xmlns:gphoto='http://schemas.google.com/photos/2007'>
      <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/photos/2007#album' />
      <title type='text'>Curling in Canada</title>
      <summary type='text'>Pictures of all my curling matches in Canada.</summary>
      <gphoto:location>Canada</gphoto:location>
      <gphoto:access>public</gphoto:access>
      <gphoto:commentingEnabled>true</gphoto:commentingEnabled>
    
    </entry>
    
    发送原始 HTTP 数据时,请注意 POSTPUT 操作需要计算 Content-Length 标头的值。您可以使用 UNIX 工具 wc 来计算此值。将 HTTP 正文的所有内容放入一个文本文件(例如 template_entry.xml,如上例中)并运行 wc -c template_entry.xml。如果您不小心针对 Content-Length 标头使用了不正确的值,则很难进行调试。
  • wget 通常用于将数据从网络服务器下载到本地文件。不过,wget 具有许多选项,能够执行与 Google 数据服务进行交互所需的所有不同类型的请求。以下示例说明了如何使用 wget POST 向 Picasa 线上影集添加新的影集条目:
    wget --post-file template_entry.xml --header "Authorization: GoogleLogin auth=ABCDEFG" --header "Content-Type: application/atom+xml" "http://picasaweb.google.com/data/feed/api/user/brad.gushue"
    
  • xsltproc 是一款将 XML 转换 (XSLT) 应用于 XML 文档的工具。它可用于轻松地从 Google 数据 API 返回的 XML 条目或 Feed 中提取所需的数据,或者生成新的条目或经过更新的条目。

总结

如您所见,c网址 和其他几种命令行工具都可通过原始 XML 和 HTTP 与 Google 数据服务轻松交互。如果您针对自己喜欢的 Google 数据 API 使用这些工具有任何疑问,请加入 API 特定论坛