使用 cURL 與 Google Data 服務互動

警告:本頁面介紹的是 Google 的舊版 API (Google Data API),僅適用於Google Data API 目錄中列出的 API,其中許多 API 都已由新版 API 取代。如需特定新 API 的相關資訊,請參閱該 API 的說明文件。如要瞭解如何使用較新的 API 授權要求,請參閱「Google 帳戶驗證和授權」。

Google Data APIs 團隊 Ryan Boyd
2007 年 9 月

簡介

Google Data API 基本上是使用 Atom 動態饋給和項目 (XML) 做為資料格式,並使用 HTTP 做為資料傳輸通訊協定,擴充 Atom 發布通訊協定。我們發布了多個用戶端程式庫,方便您與 Google Data API 互動。不過,您隨時可以使用較低層級的工具來處理我們的服務,只要稍加指引,就能輕鬆完成。

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

cURL 僅支援執行 HTTP 通訊,因此您必須瞭解Google Data 通訊協定、服務專屬通訊協定和使用的 XML 資料格式,才能使用這個應用程式。本文也會介紹其他工具,協助您輕鬆完成這些工作。

本文中的範例是以 Picasa 網路相簿資料 API 為基礎。不過,所有這些範例都能輕鬆套用至其他 Google Data API

取得及安裝 cURL

許多 UNIX/Linux 平台預設安裝的 cURL 都是常見版本。請在慣用的殼層中輸入 curl,確認工具是否已安裝並位於 PATH 中。如果沒有安裝這項工具,請前往 cURL 網站下載頁面,取得官方來源或使用者提供的二進位套件。請注意,指令列工具使用 libcurl 程式庫,這可能會以獨立的下載套件提供,因此如果您不是從來源編譯,請務必下載「二進位」套件,而不是「libcurl」套件。如要使用 cURL 取得驗證權杖,或存取部分要求使用 SSL 的 Google Data 服務,就必須使用啟用 SSL 的套件。

向 Google 資料服務驗證

如要執行已驗證的 Google 資料要求,請在要求中加入 HTTP 標頭,其中包含 ClientLogin (電腦/行動應用程式) 或 AuthSub (網路應用程式) 驗證權杖。如要使用 cURL 進行測試,ClientLogin 是較簡單的方法,詳情請參閱下文。AuthSub 驗證標頭可用於 cURL,但本文不討論如何取得權杖這項進階程序。

使用 ClientLogin

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

ClientLogin 的驗證要求會將使用者名稱、密碼和服務名稱做為表單發布變數。這些變數會分別以 EmailPasswdservice 引數的形式傳遞。這項要求會產生含有多個權杖的回應,其中一個權杖可用於向 Google Data 服務提出要求。請注意,如果使用 curl 傳遞的資料引數含有非 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 網路相簿資料 API。服務名稱 (service) 為 lh2。如要查看其他 Google 資料服務的服務名稱,請前往 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 要求,因此只需要將驗證標頭和網址傳遞至 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

這樣一來,動態消息就會變得更容易閱讀,如下所示:

<?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. PUT 將項目傳回伺服器,使用 atom:link/@rel='edit' 網址值

1. 擷取項目

您可以使用上方動態消息區塊中以粗體標示的兩個網址之一,擷取項目。所需網址是 link 元素的 href 值,且含有 rel='self'

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 服務目前不接受。如果使用 tidy,請務必在 entry 元素中,於這些屬性之間加入額外空格。

3. 更新伺服器上的項目

使用 edit URL,您需要使用 cURL 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 POSTatom:id 是由伺服器指派,因此不必納入新項目。建立新項目最簡單的方法是修改舊項目。下列範例會執行這項操作。

  1. 使用 atom:link/@rel='self' 擷取範本項目。
  2. 在本機修改範本項目,移除不必要的資訊並進行必要變更
  3. POST 使用動態消息的 post 網址,將項目傳回伺服器。這項值會顯示在擷取的動態消息中,做為 rel='http://schemas.google.com/g/2005#post'link 元素 href 值,或顯示在 http://code.google.com 上的服務說明文件中。

1. 擷取範本項目

使用 href 元素的 link 值,即可擷取單一項目,與上述範例中更新項目之前擷取項目的方式相同。rel='self'

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 和各種 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 服務目前不接受。如果使用 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 的重要功能是能夠上傳二進位物件。cURL 可輕鬆完成二進位資料和 Slug 標題的上傳作業。不過,目前 Documents List Data API 必須將 XML 連同二進位資料,以 MIME 多部分訊息的形式發布。本文不討論如何建立多部分訊息。

以下範例說明如何將名為 sweeping_the_rock.png 的圖片上傳至名為「Sweeping 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 (Google 日曆資料 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 將新相簿項目 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 是一種工具,可將 XSL 轉換 (XSLT) 套用至 XML 文件。您可以使用這個程式庫,從 Google Data API 傳回的 XML 項目或動態饋給中,輕鬆擷取所需資料位元,或是產生新的或更新的項目。

結論

如您所見,使用原始 XML 和 HTTP,即可透過 cURL 和其他指令列工具輕鬆與 Google Data 服務互動。如有任何問題,歡迎加入特定 API 論壇,與我們討論如何搭配喜愛的 Google Data API 使用這些工具。