获取Google相册中所有文件的列表

13
我的最终目标是获取我在Google Photos帐户中所有文件(照片、视频)的列表,最好还有它们的路径。 enter image description here 如果必须使用API,我宁愿使用基于.NET的API。你能提供一些方向吗?
我尝试过使用Gdata API,通过PicasaService,但是提供我的电子邮件/密码作为凭据并没有起作用,我总是得到404响应。

你找到解决办法了吗?如果没有,我相信我能为你提供一个。 - ashleedawg
不是的,我没有。如果你能分享你的方法,那就太好了。 - checho
我删除了Excel和VBA标签,因为这些在问题中甚至都没有提到,并添加了.NET标签。 - StayOnTarget
6个回答

8

如何列出您的Google照片中的所有文件:

我很惊讶花了我这么长时间才找到这个API。这不一定是“秘密信息”,但我想大多数用户都很满意以传统方式查看他们的Google照片。我的初衷是能够确定哪些照片已经正确上传,以免删除任何有价值的照片,即使是我“第三次备份副本”的旧照片。

  • 像生活中的许多事情一样,有一个“简单方法”和一个“困难方法”。

  • 根据您的观点,“困难方法”通常更有趣和/或更令人满意...


简短回答:(“简单”方法)

  1. 确保您已登录“默认”(默认)浏览器上的Google帐户

  2. 点击此处:   https://picasaweb.google.com/data/feed/api/user/default

您将获得所有Google照片相册的基于文本的列表。相册列表和照片列表看起来非常像RSS源(如果您愿意,可以将其作为书签保存)。


我知道不想手动复制照片列表,但我怀疑其他遇到这个问题的人想要“简单”的方法:

  • 打开API URL后,单击第一个相册链接。

  • Ctrl+A,然后按Ctrl+C从页面中复制文本

  • 转到您喜欢的文本编辑器(Notepad ++,Excel,oldschool Notepad等),然后按Ctrl+V

  • 返回照片列表,单击浏览器的←返回按钮,并对每个相册重复此过程

认证:首先,请确保您已从任何Google页面(例如从Google搜索页面的右上角)登录到您的Google帐户,这将允许您使用下面列出的通用地址--否则单词“default”需要替换为您的Google ID,以及其他更改以适应Google API身份验证


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]__

以编程方式检索列表:(使用“.NET API”方法)

来自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”可以代替真实的用户名,此时服务器将使用用于验证请求的当前用户凭据的用户名。
更多信息:Google Picasa .NET开发人员指南:请求照片列表

使用VBA列出所有Google照片:(使用Excel的“Web-Scrapey Way”)

Excel具有内置的XML解析功能,有各种形式:

...但即使是最新的功能似乎也不支持足够多的[我认为的] XML样式/来源的变化,无法对我有用...(或者可能是我做错了什么。

因此,我解析XML的首选方法是将其加载到一个字符串中,使用HttpRequest然后使用InstrMid来定位我感兴趣的值。这很混乱,但我已经将其用作从几种类型的站点检索几种类型的数据的“快速修复”。

在编写此答案时,我似乎已经把相关代码弄丢了(过度多任务的副作用?!)-但是如果您走到了这一步,您可能已经理解了要领。下面是从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>出现的次数将返回该页面上相册或照片的数量。


相关链接:


2
那个 PicasaWeb 链接是 404。 - Michael
1
有一天,当我有时间时,我会更新这个答案,使用oAuth和更新的Google照片API。剧透:谷歌仍然没有简化确定哪些文件占用了所有免费存储空间的过程。 - ashleedawg
我编写了一个简单的脚本(实际上有大约3个,因为我还没有适当地清理它以集成oAuth),使用API需要大约20分钟...即使一次请求100个,它通常只返回20-30个项目,而我有近10万张图片。而且你猜怎么着,你也不能用它来区分只在元数据中不同的重复项(Google让我必须重新上传,如果我重命名或添加GPS数据,而且很容易忘记定位和删除/清空垃圾桶再重新上传)。 - Michael

6

如何列出特定相册或整个库中的所有照片

已弃用的 Picasa API 可替代方案

由于 Google 已经弃用了 Picasa API,所以可以使用 Google Photos API 来获取有关相册的信息,并获得该相册中或者整个 Google Photos 库中的照片和视频列表。

这可以使用 REST、Java 或 PHP(如在其示例页面上所列)来完成。

开始吧https://developers.google.com/photos/


由 Google 提供的 Web API

您还可以通过访问示例页面上显示的 Web 上的 API 方法链接之一,轻松测试 API 功能而无需下载或编写任何内容:


为了获取特定相册中所有的照片和视频列表,请使用:

  • 搜索媒体项:https://developers.google.com/photos/library/reference/rest/v1/mediaItems/search
    • 您可以使用此方法从一个相册中列出媒体项。
    • 使用此方法,您一次只能在一个相册中列出最多100个媒体项(一页上的内容)。每个响应在末尾都会返回nextPageToken。请使用pageToken参数浏览页面。
    • 如果您需要多次执行此操作,没有问题。对于像这样简单且重复的任务,您可以利用TinyTask来记录鼠标和键盘输入,并自动化繁琐的工作

注意事项

对于简单的搜索和列出操作,您可以使用上述的 Web API,每页最多提供100个结果。对于任何更高级的操作,我建议您编写代码,以便遍历所有结果页面并存储或打印所需信息。对于不需要编码的解决方案,TinyTask 是一个不错的替代方案。


1
Google API 真正困扰我的事情是,为了设置所有身份验证相关的东西,总是很麻烦。 - Michael

5
我认为这很容易:
这是我的bash脚本:
#!/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

非常感谢!虽然有点难找到授权令牌,但我已经成功获取了 Google 相册中所有文件的列表。然而,脚本忽略了我指定的文件名,只是将一个名为“list”的文件保存在当前文件夹中,并保存了最后一个“page”文件,尽管这不是什么大问题。 - Sadi
我应该补充说明,在“过滤器”字段中输入 token 会显示授权令牌为 access_token - Sadi
大卫、萨迪和其他人,我找不到任何 access_token。我正在使用 Firefox 的 Web 开发者工具,选择了 Inspector 选项卡,并输入了过滤器“access_token”。有一行被突出显示。我尝试将其复制粘贴到文本编辑器中(选择外部和内部 HTML),但在复制的文本中找不到 access_token。请问你能给出详细的指示吗? - reikred
网络选项卡显示服务器和Web客户端之间的所有通信,例如POST和GET的URL。打开其中一个并检查标头字段。应该有一个叫做"Authorization: Bearer"的字段。在此之后的随机字符是令牌。也许在Firefox中,默认情况下不显示这些标头。请尝试使用Chrome浏览器。 - David Tristram

4
如果你想列出所有的照片并检查它们是否备份,你可以使用我的Python项目 https://pypi.org/project/gphotos-sync/,该项目使用较新的Google相册API。这将会:
  • 将所有媒体和相册索引到SQL数据库中
  • 下载本地备份(如果需要)
  • 将新的本地备份与以前的备份进行比较
  • 给出缺失于库中的文件列表
  • 给出缺失于以前备份中的文件列表
  • 给出备份文件夹中所有重复文件的列表
请注意,比较是基于文件本身的元数据进行的,而文件夹结构和文件名不需要匹配即可进行比较。

2
尝试这种方法:
  1. 选择您账户中拥有的所有照片。如果您有很多照片,可能会遇到麻烦,可以通过选择第一张照片并向下滚动来解决。图片将加载,按住Shift键使光标下方的图像悬停,因此使用Shift点击图像以尽可能多地选择。
  2. 当您有必要的选择后,单击下载图像。文件开始下载。您的任务是中断它并尝试使用某个存档查看器进入保存的文件。该文件已损坏,但至少存档将包含所有文件名。

从photos.google.com一次下载的照片数量有500张的限制。 - domen
1
这种情况下,唯一的选择是使用账户备份,在链接准备好后开始下载。 - Bryn
1
这需要很多谷歌的处理能力来打包500个文件...他们自己搞得这么难以编程,现在就该为此付出代价! - Michael
不幸的是,似乎目录实际上保存在文件的末尾,因此您无法在不下载整个文件的情况下查看zip文件中的文件。 - Michael

0
这里提供了一个带有代码的C#工作示例: https://dotnetgenetics.blogspot.com/2019/01/read-files-from-google-photos-using.html 它使用简单的mediaItems端点,以分页方式列出所有内容,但扩展到搜索媒体类型可能不太困难。
说明非常好,我以前从未编写过针对Google API的代码,但仍然很快就运行起来了。
以下是该代码的复制品,我稍微扩展了一下,以利用分页并逐渐累积所有文件而不仅仅是第一批: 数据对象:
   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

这只是一个演示,但绝对足够开始了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接