Нужна помощь в оптимизации вызовов gspread API

Я играл с gspread, чтобы передавать данные в Google Sheet, и придумал рабочий скрипт на python.

Краткая информация о «работе», которую должен выполнять этот скрипт:

  • Откройте Google Таблицу
  • Чтение имен пользователей Instagram из столбца B
  • Собирать данные из Instagram
  • Заполните данные в столбце F

Теперь, как сказано, у меня это работает с кодом внизу. Но это (по крайней мере, насколько я понимаю) использует 1 вызов API для каждой строки, которую он обновляет, но мой лист будет иметь более 1000 строк с именами пользователей, поэтому это может привести к использованию большого количества вызовов API. Поэтому я бы предпочел сделать это массово. Поэтому временно сохраните его и обновите все строки одним большим нажатием. Из документации Gspread я заметил, что это должно быть возможно, если я могу назначать точные значения ячеек и столбцов, но я не знаю, как создать исходные входные данные, чтобы облегчить это.

Мой конечный пользователь также иногда вводит пустые строки (бог знает почему...), но я заметил, что моя текущая логика заполняет здесь данные, которые на самом деле должны идти в строку ниже пустой.

Поэтому я хотел бы получить ваш отзыв о том, как я могу оптимизировать это и решить 2 «проблемы» с моим текущим скриптом:

  • уменьшить количество вызовов 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))

Вы хотите уменьшить количество звонков sheet.update_cell(). Если я правильно понял, могу я спросить вас о data = instagram_metrics(ig_url) и примерном значении data? Я думаю, что когда data помещается в массив, а массив помещается в электронную таблицу с помощью gspread, количество вызовов API листов может быть значительно уменьшено. В этой ситуации я хотел бы спросить вас о примерном значении data. Если я неправильно понял ваш вопрос, прошу прощения.

Tanaike 13.06.2019 13:59

с помощью sheet.update_cell() я обновляю по 1 ячейке за раз, поэтому практически для моего тестового файла с 500 строками я выполняю это действие 500 раз. Поэтому я хочу ограничить это и сделать это одним большим действием. Поэтому вместо записи 500 * 1 я хочу выполнить 1 запись в 500 ячеек (все с разными данными). instagram_metrics(ig_url) анализирует URL-адрес и извлекает основные данные из IG, такие как количество сообщений, имя пользователя, количество подписчиков и количество подписчиков, и возвращает их. Так данные становятся для примеров: (20, 'username', 18410, 937).

ThomasSt 13.06.2019 14:35

Спасибо за ответ и предоставленную информацию. Я думал, что могу понять ваш вопрос. Поэтому я предложил модифицированный сценарий в качестве ответа. Не могли бы вы подтвердить это? Сначала проверьте, правильно ли я понимаю ваш вопрос. Если я неправильно понял ваш вопрос, и это не тот результат, который вы хотите, приношу свои извинения.

Tanaike 14.06.2019 02:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
496
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  • Вы хотите поместить значения (data[2] из data = instagram_metrics(ig_url)) из строки 2 столбца «F».
  • Например, вы хотите поместить значение 18410 из (20, 'username', 18410, 937), полученное instagram_metrics(ig_url), в электронную таблицу.
  • Вы хотите поместить все значения «500 строк» ​​в электронную таблицу одним вызовом API.

Если я правильно понимаю, как насчет этой модификации? В этой модификации requests создается в цикле for. Затем request помещается в электронную таблицу с использованием метода update_cells().

Модифицированный скрипт:

Пожалуйста, измените следующим образом.

From:
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))
To:
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 листов.

Ссылка:

Спасибо за это! Это сработало ;) просто пришлось изменить requests = [] и производные, потому что это мешало другим функциям. Отличное решение! Спасибо

ThomasSt 14.06.2019 18:35

@ThomasSt Спасибо за ответ. Я рад, что ваша проблема была решена. И тебе спасибо.

Tanaike 14.06.2019 23:56

Другие вопросы по теме