首页 > 解决方案 > 用于创建空白文档的 Google Docs API 不会创建任何内容。如何让它创建一个空白的 Google Docs 文件?

问题描述

我正在尝试使用带有 Python 的 API 创建一个 Google Docs 文件。

我已按照他们的 API 指南和参考页面上的每条说明进行操作。

包括创建他们的快速入门脚本

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']

def main():
    SCOPES = ['https://www.googleapis.com/auth/drive.file']
    """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.pickle 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.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # 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.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('drive', 'v3', credentials=creds)

    # Call the Drive v3 API
    results = service.files().list(
        pageSize=10, fields="nextPageToken, files(id, name)").execute()
    items = results.get('files', [])

    if not items:
        print('No files found.')
    else:
        print('Files:')
        for item in items:
            print(u'{0} ({1})'.format(item['name'], item['id']))

    title = 'My Document'
    body = {
        'title': title
    }
    doc = service.files() \
        .create(body=body).execute()
    print('Created document with title: {0}'.format(
        doc.get('title')))

if __name__ == '__main__':
    main()

我希望创建一个 Google Docs 文件,但脚本返回:已创建文档,标题为:无。

它没有返回任何错误,但很明显它缺少一些东西以使其不创建文件。

我很沮丧,因为我花了 9 个小时试图让 Google Drive 自己的脚本工作。该代码是 Google Drive and Docs API 文档中的直接复制粘贴,除了我将范围从“SCOPES = [' https://www.googleapis.com/auth/drive.metadata.readonly ']”更改为“SCOPES = [' https://www.googleapis.com/auth/drive.file ']” 因为前者崩溃了,他们的 API 文档建议在尝试创建文件时使用后者作为范围。

编辑:

当前脚本:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/documents']

def main():
    """Shows basic usage of the Docs API.
    Prints the title of a sample document.
    """
    creds = None
    # The file token.pickle 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.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # 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.pickle', 'wb') as token:
            pickle.dump(creds, token)
    service = build('docs', 'v1', credentials=creds)
    title = 'My Document'
    body = {
        'title': title
    }
    doc = service.documents() \
        .create(body=body).execute()
    print('Created document with title: {0}'.format(
        doc.get('title')))
    return

if __name__ == '__main__':
    main()

我收到以下错误:

追溯

 (most recent call last):
  File "create-teamwork-sops.py", line 137, in <module>
    main()
  File "create-teamwork-sops.py", line 131, in main
    .create(body=body).execute()
  File "C:\Python27\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "C:\Python27\lib\site-packages\googleapiclient\http.py", line 855, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://docs.googleapis.com/v1/documents?alt=json returned "Request had insufficient authentication scopes.">

注意:每次更改 SCOPES 的值时,需要删除文件 token.pickle,脚本运行时会要求您登录 Google Drive 并创建一个新的 token.pickle 文件,这将允许新的要考虑的范围。

工作脚本:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request


SCOPES = ['https://www.googleapis.com/auth/drive']

def main():
    """Shows basic usage of the Docs API.
    Prints the title of a sample document.
    """
    creds = None
    # The file token.pickle 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.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # 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.pickle', 'wb') as token:
            pickle.dump(creds, token)
    # service = build('docs', 'v1', credentials=creds)
    service = build('drive', 'v3', credentials=creds)
    # title = 'My Document'
    # body = {
        # 'title': title
    # }
    # doc = service.documents() \
        # .create(body=body).execute()
    # print('Created document with title: {0}'.format(
        # doc.get('title')))

    # get folder ID
    page_token = None
    while True:
        response = service.files().list(q="mimeType = 'application/vnd.google-apps.folder'",
                                              spaces='drive',
                                              fields='nextPageToken, files(id, name)',
                                              pageToken=page_token).execute()
        for file in response.get('files', []):
            # Process change
            print('Found file: %s (%s)' % (file.get('name'), file.get('id')))
            if file.get('name')=="SOPs":
                folder_id=file.get('id')
                break
        page_token = response.get('nextPageToken', None)
        if page_token is None:
            break

    # create Google Docs file in folder
    file_metadata = {
        'name': 'my doc 2',
        'parents': [folder_id]
    }
    # media = MediaFileUpload('files/photo.jpg',
                            # mimetype='image/jpeg',
                            # resumable=True)
    file = service.files().create(body=file_metadata,
                                        # media_body=media,
                                        fields='id').execute()
    print('File ID: %s' % file.get('id'))
    return

if __name__ == '__main__':
    main()

标签: google-drive-api

解决方案


  • 您想使用 Docs API 创建新的 Google 文档。
  • 您希望将创建的新 Google 文档放入特定文件夹。
  • 您想通过 Python 使用 google-api-python-client 来实现此目的。

我可以这样理解。如果我的理解是正确的,不幸的是,当 Docs API 创建新的 Google Document 时,Document 是根文件夹。因此,当您想直接将新文档创建到特定文件夹时,请使用 Drive API。修改后的脚本如下。

从:

body = {
    'title': title
}

至:

body = {
    'name': title,
    'mimeType': 'application/vnd.google-apps.document',
    'parents': ['### folder ID ###']
}
  • 请将文件夹 ID 设置为'parents': ['### folder ID ###']

笔记:

  • 当然,通过 Docs API 将新 Document 创建到根文件夹后,可以使用 Drive API 将文件移动到特定文件夹。在这种情况下,使用了 2 个 API 调用。所以我提出了上面的修改。
  • 如果您想使用 Docs API 创建新的 Google Document,请进行如下修改。在这个修改后的脚本中,它假设您已经能够使用 Google Docs API 设置和获取 Google Document 的值。

    • doc = service.files() \
              .create(body=body).execute()
      
    • serviceForDocs = build('docs', 'v1', credentials=creds)
      doc = serviceForDocs.documents().create(body=body).execute()
      

参考:


推荐阅读