我很惊讶花了我这么长时间才找到这个API。这不一定是“秘密信息”,但我想大多数用户都很满意以传统方式查看他们的Google照片。我的初衷是能够确定哪些照片已经正确上传,以免删除任何有价值的照片,即使是我“第三次备份副本”的旧照片。
像生活中的许多事情一样,有一个“简单方法”和一个“困难方法”。
根据您的观点,“困难方法”通常更有趣和/或更令人满意...
确保您已登录“默认”(默认)浏览器上的Google帐户。
您将获得所有Google照片相册的基于文本的列表。相册列表和照片列表看起来非常像RSS源(如果您愿意,可以将其作为书签保存)。
我知道您不想手动复制照片列表,但我怀疑其他遇到这个问题的人想要“简单”的方法:
打开API URL后,单击第一个相册链接。
按Ctrl+A,然后按Ctrl+C从页面中复制文本
转到您喜欢的文本编辑器(Notepad ++,Excel,oldschool Notepad等),然后按Ctrl+V
返回照片列表,单击浏览器的返回按钮,并对每个相册重复此过程。
认证:首先,请确保您已从任何Google页面(例如从Google搜索页面的右上角)登录到您的Google帐户,这将允许您使用下面列出的通用地址--否则单词“default
”需要替换为您的Google ID,以及其他更改以适应Google API身份验证。
如果您有一个首选的发送GET请求的方法,则只需要两个URL。
据我所知,所有的Google照片都存储在相册中(即使它们看起来不是这样)。因此,要列出所有照片,必须解析所有相册,列出每个相册中的照片。
列出您的Google照片相册的GET
调用为:
https://picasaweb.google.com/data/feed/api/user/default
列出相册中所有照片的 GET
请求如下:
https://picasaweb.google.com/data/feed/api/user/default/albumid/__[albumID]__
来自Google的.NET示例:
PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri(username, albumid));
PicasaFeed feed = service.Query(query);
foreach (PicasaEntry entry in feed.Entries)
{
Console.WriteLine(entry.Title.Text);
}
default
”可以代替真实的用户名,此时服务器将使用用于验证请求的当前用户凭据的用户名。Excel具有内置的XML解析功能,有各种形式:
...但即使是最新的功能似乎也不支持足够多的[我认为的] XML样式/来源的变化,无法对我有用...(或者可能是我做错了什么。
因此,我解析XML的首选方法是将其加载到一个字符串中,使用HttpRequest
然后使用Instr
和Mid
来定位我感兴趣的值。这很混乱,但我已经将其用作从几种类型的站点检索几种类型的数据的“快速修复”。
在编写此答案时,我似乎已经把相关代码弄丢了(过度多任务的副作用?!)-但是如果您走到了这一步,您可能已经理解了要领。下面是从URL检索源的简单函数。如果您想查看其余部分,请添加评论,我会更加努力。
Public Function getHTTP(ByVal url As String) As String
'equivalent to Excel's WEBSERVICE function
Dim encResp() As Byte, xmlHTTP As Object
Set xmlHTTP = CreateObject("MSXML2.XMLHTTP") 'create XML/HTTP object
xmlHTTP.Open "GET", url, False 'initialize GET request
xmlHTTP.send 'send request to remote server
encResp = xmlHTTP.responseBody 'receive raw (encoded) response
Set xmlHTTP = Nothing 'always clean up after yourself!
getHTTP = StrConv(encResp, vbUnicode) 'return decoded response
End Function
Function countOccur(searchWithin As String, toFind As String) As String
'returns the count of occurrences of [toFind] within [searchWithin]
countOccur = UBound(Split(searchWithin, toFind))
End Function
在相册或照片页面上计算<entry>
出现的次数将返回该页面上相册或照片的数量。
由于 Google 已经弃用了 Picasa API,所以可以使用 Google Photos API 来获取有关相册的信息,并获得该相册中或者整个 Google Photos 库中的照片和视频列表。
这可以使用 REST、Java 或 PHP(如在其示例页面上所列)来完成。
开始吧:https://developers.google.com/photos/
您还可以通过访问示例页面上显示的 Web 上的 API 方法链接之一,轻松测试 API 功能而无需下载或编写任何内容:
为了获取特定相册中所有的照片和视频列表,请使用:
nextPageToken
。请使用pageToken
参数浏览页面。对于简单的搜索和列出操作,您可以使用上述的 Web API,每页最多提供100个结果。对于任何更高级的操作,我建议您编写代码,以便遍历所有结果页面并存储或打印所需信息。对于不需要编码的解决方案,TinyTask 是一个不错的替代方案。
#!/bin/bash
#
# listgp - list google photos
#
# usage: listgp <file>
#
# dumps listing of all curreent user's stored google photos in the speeceifieed file
#
# example access to google api
#
# curl 'https://photoslibrary.googleapis.com/v1/mediaItems?pageToken=CkQKQnR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnBob3Rvcy5saWJyYXJ5LnYxLkxpc3RNZWRpYUl0ZW1zUmVxdWVzdBKiAUFIX3VRNDM0V1JKaEVkcTRfYU1uUXNnUXlzdGJpUEt4enlhVXZ3QW1TUTB5cVg2SEdRRk85MjkwRlFrRVg2VlJMRVBOVnI4cHRyRWhPcE11bTN3WUFTVHNnTXNFdmc5eUtaODd6TFJsLXh2QjNnSUlabWpLZl9sZV81c2lMc1VCUmhsalNFRXowWm9lazVhczQtNXB0dkJtYzduYUs1b1Vidw' --header 'Authorization: Bearer ya29.GmTMBkWYE5CNTCSKJJTqlSh7FohUHp6u0hWTiyevsIW5iEGbBC0lmExfCNAldH8kaKBkwszW3Pk-ZwAzFMPNXtM4RlBF8M4vgbf8Lzv99LiVxWtojooSnRxOHWqq7ZEm-4sE9NI-' --header 'Accept: application/json' --compressed
#
# to determine your auth token,
# see https://developers.google.com/photos/library/reference/rest/v1/mediaItems/list
# open dev tools in chrome, go to network tab, run the example, log into your google photos account
# you can inpect the headers and find one that has 'Authorization: Bearer '. Copy and paste your token
# in the script below as the value for 'auth'.
#
#
auth="ya29.GmPNBqtRiw1dvOdiqjoaRkG9CtO2gunFtV8u_00vsAHROatuT5gZlFwNjmXf-CiPxOqxdgDKmweTdZIXeOCVaMM7d8n7E9VQlxAKOZo1zyE5Gq0_Nqqpc7T6csUJ5wablvhajQw"
#
function getItems() {
pageToken=$1;
if [ "$pageToken" != "" ]
then
pageTokenParam=pageToken="$pageToken";
else
pageTokenParam="";
fi
curl \
"https://photoslibrary.googleapis.com/v1/mediaItems?$pageTokenParam" \
--header "Authorization: Bearer $auth" \
--header 'Accept: application/json'\
--compressed > page
cat page >> list
grepOut=(`grep nextPageToken page | sed s/\"//g`)
if [ "${grepOut[0]}" == "" ]
then
exit;
fi
getItems ${grepOut[1]}
}
getItems
mediaItems
端点,以分页方式列出所有内容,但扩展到搜索媒体类型可能不太困难。 public class clsResponseRootObject
{
public List<MediaItem> mediaItems { get; set; }
public string nextPageToken { get; set; }
}
public class MediaItem
{
public string id { get; set; }
public string productUrl { get; set; }
public string baseUrl { get; set; }
public string mimeType { get; set; }
public MediaMetadata mediaMetadata { get; set; }
public string filename { get; set; }
}
public class MediaMetadata
{
public DateTime creationTime { get; set; }
public string width { get; set; }
public string height { get; set; }
public Photo photo { get; set; }
}
public class Photo
{
public string cameraMake { get; set; }
public string cameraModel { get; set; }
public double focalLength { get; set; }
public double apertureFNumber { get; set; }
public int isoEquivalent { get; set; }
}
主程序:
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util.Store;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
namespace GooglePhotosAPISimpleDemo
{
class Program
{
static void Main(string[] args)
{
string credPath = @"D:\StorePath\";
clsResponseRootObject responseObject = new clsResponseRootObject();
UserCredential credential;
string[] scopes = {
"https://www.googleapis.com/auth/photoslibrary.sharing",
"https://www.googleapis.com/auth/photoslibrary.readonly"
};
string UserName = "your_googlemail_account";
string ClientID = "your_client_id";
string ClientSecret = "your_client_secret";
using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
scopes,
UserName,
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
try
{
var done = false;
var pageToken = "";
var count = 0;
Console.WriteLine("------------------------Retrieving media files--------------------------------");
while (!done)
{
var url = "https://photoslibrary.googleapis.com/v1/mediaItems";
url += "?pageSize=100";
url += $"&pageToken={pageToken}";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("client_id", ClientID);
httpWebRequest.Headers.Add("client_secret", ClientSecret);
httpWebRequest.Headers.Add("Authorization:" + credential.Token.TokenType + " " + credential.Token.AccessToken);
httpWebRequest.Method = "GET";
HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse;
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
responseObject = JsonConvert.DeserializeObject<ResponseRootObject>(reader.ReadToEnd());
if (responseObject != null && responseObject.mediaItems != null && responseObject.mediaItems.Count > 0)
{
foreach (var item in responseObject.mediaItems)
{
Console.WriteLine($"{++count}, {item.filename}, {item.mimeType}");
}
pageToken = responseObject.nextPageToken;
}
else
{
done = true;
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error occured: " + ex.Message);
}
Console.ReadLine();
}
}
}
示例输出:
------------------------Retrieving media files--------------------------------
1, IMG_20220222_132730954_HDR.jpg, image/jpeg
2, IMG_20220222_132729262_HDR.jpg, image/jpeg
3, IMG_20220222_132725134_HDR.jpg, image/jpeg
4, IMG_20220222_132721824_HDR.jpg, image/jpeg
5, IMG_20220222_132718255_HDR.jpg, image/jpeg
6, IMG_20220222_132717466_HDR.jpg, image/jpeg
7, IMG_20220222_132716075_HDR.jpg, image/jpeg
8, IMG_20220222_132554519.jpg, image/jpeg
9, IMG_20220222_132552091.jpg, image/jpeg
10, IMG_20220222_132549638.jpg, image/jpeg
11, IMG_20220222_132227628_HDR.jpg, image/jpeg
这只是一个演示,但绝对足够开始了。