如何通过 python 中安装的 google 驱动器文件的路径获取 file/folder 的共享 link?

How can I get share link of file/folder by path to the file on insalled google drive in python?

我在我的计算机上安装了 Google 驱动器 (Windows 11 x64) 来驱动 G:\ 我希望能够为我有路径的特定 file/folder 获取共享 link。 Google 驱动器将有重复的 file/folder。 我怎样才能用 python 做到这一点? 提前致谢

已编辑: 我设法获得了特定文件名的 link,但现在如果 Google 驱动器中有 2 个以上具有相同文件名的文件,我就会遇到问题。 例如,我想要此文件 G:\RootFolder\Subfolder1\Subfolder2\myfile.txt 的 link,但还有另一个同名文件 G:\RootFolder\Subfolder3\Subfolder4\Subfolder5\myfile.txt。我怎样才能只为 G:\RootFolder\Subfolder1\Subfolder2\myfile.txt 提供 link?

from Google import Create_Service

CLIENT_SECRET_FILE = 'client-secret.json'
API_NAME = 'drive'
API_VERSION = 'v3'
SCOPES = ['https://www.googleapis.com/auth/drive']

service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)

# Update Sharing Setting
file_id = '<file id>'

request_body = {
    'role': 'reader',
    'type': 'anyone'
}

response_permission = service.permissions().create(
    fileId=file_id,
    body=request_body
).execute()

print(response_permission)


# Print Sharing URL
response_share_link = service.files().get(
    fileId=file_id,
    fields='webViewLink'
).execute()

print(response_share_link)

# Remove Sharing Permission
service.permissions().delete(
    fileId=file_id,
    permissionId='anyoneWithLink'
).execute()

我设法创建了适合我的脚本。 套餐:pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

from __future__ import print_function
import argparse
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


# According the guide https://developers.google.com/drive/api/quickstart/python
# TODO: First time - Create "credentials.json" file https://developers.google.com/workspace/guides/create-credentials#oauth-client-id
# TODO: First time - Enable the Google Drive API https://developers.google.com/drive/api/guides/enable-drive-api


def is_folder_name_in_parents(service, parents, folder_name):
    for parent_id in parents:
        response = service.files().get(fileId=parent_id, fields='name').execute()
        if folder_name == response.get("name"):
            return parent_id
    return None


def is_correct_file_path(service, folder_path, parents, root_folder_name, root_folder_id):
    folder_name = os.path.basename(folder_path)
    if folder_name == root_folder_name and root_folder_id in parents:
        return True
    parent_id = is_folder_name_in_parents(service=service, parents=parents, folder_name=folder_name)
    if not parent_id:
        return False
    response = service.files().get(fileId=parent_id, fields='parents').execute()
    new_parents = response.get("parents")
    return is_correct_file_path(service=service,
                                folder_path=os.path.dirname(folder_path),
                                parents=new_parents,
                                root_folder_name=root_folder_name,
                                root_folder_id=root_folder_id)


def get_sharing_link_by_path(root_folder_name, root_folder_id, filepath):
    # If modifying these scopes, delete the file token.json.
    SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']

    """Shows basic usage of the Drive v3 API.
    Prints the names and ids of the first 10 files the user has access to.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    try:
        service = build('drive', 'v3', credentials=creds)
        filename = os.path.basename(filepath)
        folder_path = os.path.dirname(filepath)
        page_token = None
        while True:
            response = service.files().list(
                q=f"name='{filename}'",
                spaces='drive',
                fields='nextPageToken, files(name, webViewLink, parents)',
                pageToken=page_token
            ).execute()
            print(f"There are {len(response.get('files', []))} results in Google Drive for: {filename}")
            for file in response.get('files', []):
                if "parents" in file.keys():
                    if is_correct_file_path(service=service,
                                            folder_path=folder_path,
                                            parents=file["parents"],
                                            root_folder_name=root_folder_name,
                                            root_folder_id=root_folder_id):
                        if 'webViewLink' in file.keys():
                            print(f"File path: {filename}\nWeb View Link: {file['webViewLink']}")
                            return file['webViewLink']
                        print(f"Web view link for this file not found: {filepath}")
                        return None
            page_token = response.get('nextPageToken', None)
            if page_token is None:
                print(f"File not found: {filepath}")
                return None
    except HttpError as error:
        # TODO(developer) - Handle errors from drive API.
        print(f'An error occurred: {error}')