需要帮助优化 gspread API 调用
Need help optimizing gspread API calls
我一直在尝试使用 gspread 将数据推送到 Google Sheet,并在 python 中提出了一个工作脚本。
"job" 这个脚本必须做的快速背景:
- 打开GoogleSheet
- 从 B 列读取 Instagram 用户名
- 从 Instagram 收集数据
- 填写F列数据
现在,如前所述,我使用下面的代码进行了此操作。但这确实(至少据我所知)每行更新使用 1 API 调用,但我的 sheet 将有 1000 多行用户名,所以这最终可能会使用很多 API 电话。所以我更愿意批量执行此操作。所以暂时存储它并在 1 次大推送中更新所有行。从 Gspread 文档中,我注意到如果我可以分配精确的单元格和列值应该是可能的,但我不知道如何建立我的原始输入数据来促进这一点。
我的最终用户偶尔也会输入空行(天知道为什么..)但我注意到我当前的逻辑在这里填充数据,这实际上需要转到空行下面的行。
所以我很想听取您的意见,了解我如何优化它,并用我当前的脚本解决 2 'issues':
- 减少 API 调用次数
- 正确处理空行
这是我的代码:
#import Google
import gspread
from oauth2client.service_account import ServiceAccountCredentials
#Setting up connection to Google Sheet and picking up the initial values
scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('file_init.json',scope)
client = gspread.authorize(creds)
sheet = client.open('Workbookname').sheet1
pp = pprint.PrettyPrinter()
ig_username_column = 2
ig_data_column = 6
ig_usernames = sheet.col_values(ig_username_column)
ig_names = []
i = 2
t = 2
for user in ig_usernames:
ig_clean = remove_prefix(user,'@')
ig_names.append(ig_clean)
print(ig_names)
for name in ig_names[1:]:
if len(name) != 0:
print(name)
ig_url = f'https://www.instagram.com/{name}'
print(ig_url)
data = instagram_metrics(ig_url)
sheet.update_cell(i, ig_data_column, data[2])
i += 1
else:
i += 1 #this is here to skip over empty rows in the Sheet
continue
sleep(randint(3,6))
- 您想要从第 2 列的 "F".
中输入值(data[2]
,共 data = instagram_metrics(ig_url)
)
- 例如,您要将
instagram_metrics(ig_url)
检索到的 (20, 'username', 18410, 937)
的 18410
的值放入电子表格。
- 您想通过一次 API 调用将“500 行”的所有值放入电子表格。
如果我的理解是正确的,这个修改怎么样?在此修改中,requests
是在 for 循环中创建的。然后,使用 update_cells()
.
的方法将 request
放入电子表格
修改后的脚本:
请修改如下
从:
for name in ig_names[1:]:
if len(name) != 0:
print(name)
ig_url = f'https://www.instagram.com/{name}'
print(ig_url)
data = instagram_metrics(ig_url)
sheet.update_cell(i, ig_data_column, data[2])
i += 1
else:
i += 1 #this is here to skip over empty rows in the Sheet
continue
sleep(randint(3,6))
到:
requests = []
for name in ig_names[1:]:
if len(name) != 0:
print(name)
ig_url = f'https://www.instagram.com/{name}'
print(ig_url)
data = instagram_metrics(ig_url)
requests.append(data[2])
else:
requests.append('')
continue
# Select a range
cell_list = worksheet.range('F2:F' + str(len(requests) + 1))
for i, cell in enumerate(cell_list):
cell.value = requests[i]
# Update in batch
worksheet.update_cells(cell_list)
注:
- 我认为在这个修改中,可能不需要
sleep(randint(3,6))
。
- 此修改后的脚本假设您已经能够使用表格写入和读取值 API。
参考:
我一直在尝试使用 gspread 将数据推送到 Google Sheet,并在 python 中提出了一个工作脚本。
"job" 这个脚本必须做的快速背景:
- 打开GoogleSheet
- 从 B 列读取 Instagram 用户名
- 从 Instagram 收集数据
- 填写F列数据
现在,如前所述,我使用下面的代码进行了此操作。但这确实(至少据我所知)每行更新使用 1 API 调用,但我的 sheet 将有 1000 多行用户名,所以这最终可能会使用很多 API 电话。所以我更愿意批量执行此操作。所以暂时存储它并在 1 次大推送中更新所有行。从 Gspread 文档中,我注意到如果我可以分配精确的单元格和列值应该是可能的,但我不知道如何建立我的原始输入数据来促进这一点。
我的最终用户偶尔也会输入空行(天知道为什么..)但我注意到我当前的逻辑在这里填充数据,这实际上需要转到空行下面的行。
所以我很想听取您的意见,了解我如何优化它,并用我当前的脚本解决 2 'issues':
- 减少 API 调用次数
- 正确处理空行
这是我的代码:
#import Google
import gspread
from oauth2client.service_account import ServiceAccountCredentials
#Setting up connection to Google Sheet and picking up the initial values
scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('file_init.json',scope)
client = gspread.authorize(creds)
sheet = client.open('Workbookname').sheet1
pp = pprint.PrettyPrinter()
ig_username_column = 2
ig_data_column = 6
ig_usernames = sheet.col_values(ig_username_column)
ig_names = []
i = 2
t = 2
for user in ig_usernames:
ig_clean = remove_prefix(user,'@')
ig_names.append(ig_clean)
print(ig_names)
for name in ig_names[1:]:
if len(name) != 0:
print(name)
ig_url = f'https://www.instagram.com/{name}'
print(ig_url)
data = instagram_metrics(ig_url)
sheet.update_cell(i, ig_data_column, data[2])
i += 1
else:
i += 1 #this is here to skip over empty rows in the Sheet
continue
sleep(randint(3,6))
- 您想要从第 2 列的 "F". 中输入值(
- 例如,您要将
instagram_metrics(ig_url)
检索到的(20, 'username', 18410, 937)
的18410
的值放入电子表格。 - 您想通过一次 API 调用将“500 行”的所有值放入电子表格。
data[2]
,共 data = instagram_metrics(ig_url)
)
如果我的理解是正确的,这个修改怎么样?在此修改中,requests
是在 for 循环中创建的。然后,使用 update_cells()
.
request
放入电子表格
修改后的脚本:
请修改如下
从:for name in ig_names[1:]:
if len(name) != 0:
print(name)
ig_url = f'https://www.instagram.com/{name}'
print(ig_url)
data = instagram_metrics(ig_url)
sheet.update_cell(i, ig_data_column, data[2])
i += 1
else:
i += 1 #this is here to skip over empty rows in the Sheet
continue
sleep(randint(3,6))
到:
requests = []
for name in ig_names[1:]:
if len(name) != 0:
print(name)
ig_url = f'https://www.instagram.com/{name}'
print(ig_url)
data = instagram_metrics(ig_url)
requests.append(data[2])
else:
requests.append('')
continue
# Select a range
cell_list = worksheet.range('F2:F' + str(len(requests) + 1))
for i, cell in enumerate(cell_list):
cell.value = requests[i]
# Update in batch
worksheet.update_cells(cell_list)
注:
- 我认为在这个修改中,可能不需要
sleep(randint(3,6))
。 - 此修改后的脚本假设您已经能够使用表格写入和读取值 API。