使用 cURL 與 Google Data 服務互動

警告:本頁面說明 Google 的舊版 API (即 Google Data API);該 API 只與 Google Data API 目錄中列出的 API 相關,其中許多 API 已由新版 API 取代。如需特定新的 API 的相關資訊,請參閱新 API 的說明文件。如要瞭解如何使用新版 API 授權要求,請參閱 Google 帳戶驗證與授權

Google Data API 團隊的 Ryan Boyd
2007 年 9 月

簡介

基本上,Google Data API 使用 Atom 資訊提供和項目 (XML) 做為資料格式,並使用 HTTP 做為資料傳輸的通訊協定 - 擴充 Atom 發布通訊協定。我們發布了許多用戶端程式庫,讓您更容易與 Google Data API 互動。不過,您隨時可以選擇使用較低層級的工具,以便與 Google 服務搭配使用,而且只要按照我們的指示操作,就能輕鬆上手。

cURL 是一個指令列應用程式,可透過各種通訊協定 (包括 HTTP) 執行要求。開發人員通常會使用 cURL 來測試 Google Data 服務,因為它支援低層級與 API 互動所需的 HTTP 功能。

cURL 僅支援執行 HTTP 通訊,因此,如要使用 Google Data 通訊協定、服務專屬通訊協定和 XML 資料格式,是與應用程式互動的先決條件。本文將提及其他工具,協助您輕鬆完成這些工作。

本文使用 Picasa Picasa 網路相簿資料 API 的範例。不過,這些範例都可以輕鬆套用到其他 Google Data API

取得並安裝 cURL

cURL 通常用於多個 UNIX/Linux 平台的預設安裝。請在您喜愛的殼層中輸入 curl,看看工具是否已安裝且位於您的 PATH 中。如果您沒有安裝這個工具,請前往 cURL 網站下載網頁,取得官方來源或使用者提供的二進位檔套件。請注意,指令列工具會使用 libcurl 程式庫,此程式庫可能會以個別下載套件的形式提供。因此,如果您不是從原始碼進行編譯,請務必下載「二進位檔」套件,而非「libcurl」套件。如果您想使用 cURL 取得驗證權杖,或需要需要使用 SSL 才能請求某些 Google 資料服務,就必須啟用 SSL 套件。

驗證 Google Data Service

ClientLogin (電腦版/行動應用程式) 或 AuthSub (網路應用程式) 驗證權杖的要求加入要求中加入 HTTP 標頭,以執行經過驗證的 Google Data 要求。使用 cURL 進行測試時,ClientLogin 是較簡單的方法,詳見下文。AuthSub 驗證標頭可以與 cURL 搭配使用,但取得憑證的更進階程序不在本文的討論範圍內。

使用 ClientLogin

ClientLogin 適用於安裝版 (電腦版/行動版) 應用程式。使用這種驗證方法時,使用 Google Data API 的應用程式會直接處理使用者的使用者名稱和密碼。

ClientLogin 的驗證要求是以使用者名稱、密碼和服務名稱做為表單訊息的變數。這些變數會分別以 EmailPasswdservice 引數的形式傳遞。此要求會產生數個憑證,而其中一個憑證可用來向 Google Data 服務發出要求。請注意,如果透過 curl 傳送的資料引數包含 URL 編碼,則包含非 ASCII 字元 (通常是出現在 EmailPasswd 引數中)。您可以使用 --data-urlencode 旗標,要求 curl 對這些引數進行網址編碼。

要求範例:

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

如需上述要求中所用參數的詳細資訊,請參閱 ClientLogin 說明文件。在這個範例中,我們所使用的服務是 Picasa Web 網路相簿資料 API。服務名稱 (service) 為 lh2。其他 Google Data 服務的服務名稱,請參閱 Google Data API 常見問題網頁。

在上述回應中,Auth 符記的值是驗證 Google Data 服務的唯一必要值。此憑證的值會形成為 HTTP 標頭,用於對 Google Data 服務發出的每個要求。

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

注意:以反斜線字元 ('\') 逸出換行的方法在 Windows 指令殼層中無法運作,因此您必須在 Windows 上執行 curl 時,必須在同一行輸入整個指令。


擷取資訊提供和項目

在 Google Data API 中,系統會透過一組選擇性的查詢參數執行 HTTP GET,以擷取資訊提供和項目。由於我們執行的是 GET 要求,所以只需將 auth 標頭和 URL 傳遞至 curl。下方範例將繼續使用 Picasa Web 網路相簿資料 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

這樣可以更容易閱讀,如下所示:

<?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>

如要擷取個別項目,您可以透過相同方式擷取項目網址,而非動態饋給網址。

正在更新項目

Google Data API 中的項目會於編輯網址的 HTTP PUT 中,透過要求內文中的新項目 XML 副本來更新。

  1. 使用 atom:link/@rel='self' 網址值擷取項目
  2. 在本機更新項目,進行必要的變更
  3. 使用 atom:link/@rel='edit' 網址值將 PUT 傳回伺服器

1. 擷取項目

您可以使用上方資訊提供區塊中以粗體標示的兩個網址,擷取該項目。所需網址是包含 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 Data Services 目前不接受。如果您使用的是 tidy,請務必在 entry 元素的屬性之間加入額外空格。

3. 更新伺服器上的項目

使用 edit URL,您需要 PUT 使用 cURL 共享到服源的複本。請新增標頭,用來指出傳送至伺服器的內容類型。下列程式碼片段假設具有更新項目的檔案儲存在 update_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. POST 項目傳回伺服器,並使用動態饋給的 post 網址。可以在已擷取的資訊提供中找到 href 值的 link 元素 rel='http://schemas.google.com/g/2005#post',或是 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. 修改範本項目

我們想建立一個最近在冰壺比賽中的照片,名為「Curling in Canada」。Google 資料可讓您刪除伺服器提供值的 Atom 元素,因此為了建立這個簡單的範本項目,我們將移除動態饋給中的 atom:idatom:publishedatom:updatedatom:author 和各種 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 Data Services 目前不接受。如果您使用的是 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 Web 網路相簿資料 API 和 Documents List data API 是一項重要功能,就是能夠上傳二進位物件。cURL 可輕鬆完成二進位資料和上傳標頭。不過,「Document List 資料 API」目前需要將 XML 和二進位資料張貼為 MIME 多部分訊息。撰寫多部分訊息並不在本文的討論範圍內。

以下範例說明如何將名為 sweeping_the_rock.png 的圖片上傳到 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 Data 服務互動。請注意,並非所有 Google 資料服務都支援 SSL。開啟連結的方法如下:
    • telnet picasaweb.google.com 80 (Picasa Web 網路相簿資料 API)
    • openssl s_client -connect www.google.com:443 (Google Calendar Data API 和 www.google.com 上的其他服務)
    建立連線之後,您必須傳送原始 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 為新的「Picasa 網路相簿」POST建立相簿項目:
    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"
    
  • 改變」工具可用於將 XSL 轉換 (GSA) 套用至 XML 文件。此 API 可用於輕鬆從 Google Data API 傳回的 XML 項目或資訊提供,輕鬆擷取需要的資料片段,也可產生新的項目或更新項目。

結語

如您所見,cURL 和其他數種指令列工具能夠讓您透過原始 XML 與 HTTP 輕鬆與 Google 資料服務互動。如果您對使用這些工具搭配喜愛的 Google Data API 有任何疑問,歡迎前往 API 相關論壇與我們討論。