错误从Google驱动器下载文件

发布于 2025-01-25 02:38:46 字数 3643 浏览 5 评论 0原文

我将一些图像从Google Earth Engine出口到Google Drive。我需要使用Python脚本将这些图像下载到本地驱动器。然后,我尝试使用 oauth2client apiclient 正如我所看到的在这里

我在驱动器和相应的ID中获得了一个文件列表,然后我使用ID尝试使用 gdown lib下载文件:

gdown.download(f'https://drive.google.com/uc?id={file_data["id"]}',
                       f'{download_path}{os.sep}{filename_to_download}.tif')

我收到以下错误消息:

Access denied with the following error:
    Cannot retrieve the public link of the file. You may need to change
    the permission to 'Anyone with the link', or have had many accesses. 
You may still be able to access the file from the browser:
     https://drive.google.com/uc?id=<id> 

当我获得驱动器文件列表时,我想驱动器身份验证还可以。如果我使用浏览器中建议的错误消息建议的链接,则可以下载该文件。如果在驱动器上检查文件属性,我可以看到:

谁可以访问:未共享。

我应该怎么做才能下载文件?

这是完整的代码:

# https://medium.com/swlh/google-drive-api-with-python-part-i-set-up-credentials-1f729cb0372b
# https://levelup.gitconnected.com/google-drive-api-with-python-part-ii-connect-to-google-drive-and-search-for-file-7138422e0563
# https://stackoverflow.com/questions/38511444/python-download-files-from-google-drive-using-url
import os
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools
import gdown

class GoogleDrive(object):
    # define API scope
    def __init__(self, secret_credentials_file_path = './credentials'):
        self.DriveFiles = None
        SCOPE = 'https://www.googleapis.com/auth/drive'
        self.store = file.Storage(f'{secret_credentials_file_path}{os.sep}credentials.json')
        self.credentials = self.store.get()
        if not self.credentials or self.credentials.invalid:
            flow = client.flow_from_clientsecrets(f'{secret_credentials_file_path}{os.sep}client_secret.json',
                                                  SCOPE)
            self.credentials = tools.run_flow(flow, self.store)
        oauth_http = self.credentials.authorize(Http())
        self.drive = discovery.build('drive', 'v3', http=oauth_http)

    def RetrieveAllFiles(self):
        results = []
        page_token = None

        while True:
            try:
                param = {}

                if page_token:
                    param['pageToken'] = page_token

                files = self.drive.files().list(**param).execute()
                # append the files from the current result page to our list
                results.extend(files.get('files'))
                # Google Drive API shows our files in multiple pages when the number of files exceed 100
                page_token = files.get('nextPageToken')

                if not page_token:
                    break

            except Exception as error:
                print(f'An error has occurred: {error}')
                break
        self.DriveFiles = results

    def GetFileData(self, filename_to_search):
        for file_data in self.DriveFiles:
            if file_data.get('name') == filename_to_search:
                return file_data
        else:
            return None

    def DownloadFile(self, filename_to_download, download_path):
        file_data = self.GetFileData(f'{filename_to_download}.tif')
        gdown.download(f'https://drive.google.com/uc?id={file_data["id"]}',
                       f'{download_path}{os.sep}{filename_to_download}.tif')

I exported some images from Google Earth Engine to Google Drive. I need to download those images to a local drive using a Python script. Then, I tried to use oauth2client, apiclient as I saw here:

I got a list of files in Drive and the corresponding IDs, then I use the ID to try to download the file using the gdown lib:

gdown.download(f'https://drive.google.com/uc?id={file_data["id"]}',
                       f'{download_path}{os.sep}{filename_to_download}.tif')

I got the following error message:

Access denied with the following error:
    Cannot retrieve the public link of the file. You may need to change
    the permission to 'Anyone with the link', or have had many accesses. 
You may still be able to access the file from the browser:
     https://drive.google.com/uc?id=<id> 

As I got the Drive file list, I suppose that the Drive authentication is ok. If I use the error message suggested link in the browser, I can download the file. If a check file properties at Drive, I can see:

Who can access: not shared.

What should I do to download the files?

This is the complete code:

# https://medium.com/swlh/google-drive-api-with-python-part-i-set-up-credentials-1f729cb0372b
# https://levelup.gitconnected.com/google-drive-api-with-python-part-ii-connect-to-google-drive-and-search-for-file-7138422e0563
# https://stackoverflow.com/questions/38511444/python-download-files-from-google-drive-using-url
import os
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools
import gdown

class GoogleDrive(object):
    # define API scope
    def __init__(self, secret_credentials_file_path = './credentials'):
        self.DriveFiles = None
        SCOPE = 'https://www.googleapis.com/auth/drive'
        self.store = file.Storage(f'{secret_credentials_file_path}{os.sep}credentials.json')
        self.credentials = self.store.get()
        if not self.credentials or self.credentials.invalid:
            flow = client.flow_from_clientsecrets(f'{secret_credentials_file_path}{os.sep}client_secret.json',
                                                  SCOPE)
            self.credentials = tools.run_flow(flow, self.store)
        oauth_http = self.credentials.authorize(Http())
        self.drive = discovery.build('drive', 'v3', http=oauth_http)

    def RetrieveAllFiles(self):
        results = []
        page_token = None

        while True:
            try:
                param = {}

                if page_token:
                    param['pageToken'] = page_token

                files = self.drive.files().list(**param).execute()
                # append the files from the current result page to our list
                results.extend(files.get('files'))
                # Google Drive API shows our files in multiple pages when the number of files exceed 100
                page_token = files.get('nextPageToken')

                if not page_token:
                    break

            except Exception as error:
                print(f'An error has occurred: {error}')
                break
        self.DriveFiles = results

    def GetFileData(self, filename_to_search):
        for file_data in self.DriveFiles:
            if file_data.get('name') == filename_to_search:
                return file_data
        else:
            return None

    def DownloadFile(self, filename_to_download, download_path):
        file_data = self.GetFileData(f'{filename_to_download}.tif')
        gdown.download(f'https://drive.google.com/uc?id={file_data["id"]}',
                       f'{download_path}{os.sep}{filename_to_download}.tif')

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏有森光若流苏 2025-02-01 02:38:46

Google Drive可能不是最佳工具,您可能需要将其上传到IMGUR等原始文件托管服务中,并使用请求下载到文件,然后您可以使用脚本读取文件,或者您甚至没有将其写入文件,然后只使用image.content而不是指定图像。以下是一个示例:(

image = requests.get("https://i.imgur.com/5SMNGtv.png")
with open("image.png", 'wb') as file:
    file.write(image.content)

您可以通过在文件名之前添加路径下载文件的位置,如这样:)

image = requests.get("https://i.imgur.com/5SMNGtv.png")
with open("C://Users//Admin//Desktop//image.png", 'wb') as file:
    file.write(image.content)

Google drive may not be the best tool for this, you may want to upload them into a RAW file hosting service like Imgur and download it to a file using requests, you can then read the file using the script or you don't even have to write it to the file and just use image.content instead to specify the image. Here's an example:

image = requests.get("https://i.imgur.com/5SMNGtv.png")
with open("image.png", 'wb') as file:
    file.write(image.content)

(You can specify the location of where you want the file to download by adding the PATH before the file name, like this:)

image = requests.get("https://i.imgur.com/5SMNGtv.png")
with open("C://Users//Admin//Desktop//image.png", 'wb') as file:
    file.write(image.content)
天气好吗我好吗 2025-02-01 02:38:46

解决方案1。

Access denied with the following error:
 Cannot retrieve the public link of the file. You may need to change
 the permission to 'Anyone with the link', or have had many accesses. 
You may still be able to access the file from the browser:
 https://drive.google.com/uc?id=<id> 

在GDRIVE上的“共享”选项卡中(右键单击映像,打开共享或获得链接),请更改具有链接的任何人的隐私。希望您的代码应该起作用。

解决方案2。

如果您可以使用Google Colab,则可以轻松安装GDRIVE,并使用

from google.colab import drive
drive.mount('/content/gdrive')

Solution 1.

Access denied with the following error:
 Cannot retrieve the public link of the file. You may need to change
 the permission to 'Anyone with the link', or have had many accesses. 
You may still be able to access the file from the browser:
 https://drive.google.com/uc?id=<id> 

In the sharing tab on gdrive (Right click on image, open Share or Get link), please change privacy to anyone with the link. Hopefully your code should work.
Step 2
Step 1

Solution 2.

If you can use Google Colab, then you can mount gdrive easily and access files there using

from google.colab import drive
drive.mount('/content/gdrive')
梦里寻她 2025-02-01 02:38:46

Google拥有此政策,即他们不接受您的常规Google/gmail-password。他们只接受所谓的“应用程序密码”,您需要为Google-Account创建所谓的“ App密码”,以便对您使用第三部分应用程序进行身份验证

Google has this policy that they do not accept your regular google-/gmail-password. They only accept so called "App Passwords" that you need to create for your google-account in order to authenticate if you are using thirdparty apps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文