2017-08-28 96 views
0

我目前正在製作一個連接到Google電子表格(gspread)的Discord-bot。 但我運行一段時間後,它開始發出錯誤,它不能連接到我的gspread了(除非我重新啓動它)。Python - Gspread請求錯誤401

是我收到的錯誤:(https://hastebin.com/odutucawuv.tex

Ignoring exception in command sub 
Traceback (most recent call last): 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\core.py", line 50, in wrapped 
ret = yield from coro(*args, **kwargs) 
File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 65, in sub 
val = worksheet.cell(cell_name.row, cell_name.col+4) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\models.py", line 392, in cell 
self._cell_addr(row, col)) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\client.py", line 210, in get_cells_cell_id_feed 
r = self.session.get(url) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\httpsession.py", line 73, in get 
return self.request('GET', url, params=params, **kwargs) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\httpsession.py", line 69, in request 
response.status_code, response.content)) 
gspread.exceptions.RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'') 

The above exception was the direct cause of the following exception: 

Traceback (most recent call last): 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\bot.py", line 846, in process_commands 
yield from command.invoke(ctx) 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\core.py", line 374, in invoke 
yield from injected(*ctx.args, **ctx.kwargs) 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\core.py", line 54, in wrapped 
raise CommandInvokeError(e) from e 
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: 
RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'') 
Ignoring exception in command add 
Traceback (most recent call last): 
File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 130, in add 
cell_name = worksheet.find(str(member)) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\models.py", line 711, in find 
return self._finder(finditem, query) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\models.py", line 696, in _finder 
cells = self._fetch_cells() 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\models.py", line 331, in _fetch_cells 
feed = self.client.get_cells_feed(self) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\client.py", line 176, in get_cells_feed 
r = self.session.get(url) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\httpsession.py", line 73, in get 
return self.request('GET', url, params=params, **kwargs) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\httpsession.py", line 69, in request 
response.status_code, response.content)) 
gspread.exceptions.RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'') 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\core.py", line 50, in wrapped 
ret = yield from coro(*args, **kwargs) 
File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 136, in add 
cell_list = worksheet.range('A2:A100') 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\models.py", line 72, in wrapper 
return method(self, *args, **kwargs) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\models.py", line 412, in range 
params={'range': name, 'return-empty': 'true'} 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\client.py", line 176, in get_cells_feed 
r = self.session.get(url) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\httpsession.py", line 73, in get 
return self.request('GET', url, params=params, **kwargs) 
File "C:\Python36\lib\site-packages\gspread-0.6.2- 
py3.6.egg\gspread\httpsession.py", line 69, in request 
response.status_code, response.content)) 
gspread.exceptions.RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'') 

The above exception was the direct cause of the following exception: 

Traceback (most recent call last): 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\bot.py", line 846, in process_commands 
yield from command.invoke(ctx) 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\core.py", line 374, in invoke 
yield from injected(*ctx.args, **ctx.kwargs) 
File "C:\Python36\lib\site-packages\discord.py-0.16.10- 
py3.6.egg\discord\ext\commands\core.py", line 54, in wrapped 
raise CommandInvokeError(e) from e 
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: 
RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'') 

和我使用,如果是任何人的幫助,瞭解上述問題的一個功能,我可以提供更多的我的代碼如果有必要修復它:

import discord 
import asyncio 
import random 
import pickle 
import os 
import gspread 
import time 

from oauth2client.service_account import ServiceAccountCredentials 
from discord.ext import commands 

prefix = '!' 

def returnPrefix(): 
    global prefix 
    return prefix 

bot = commands.Bot(returnPrefix()) 

scope = ['https://spreadsheets.google.com/feeds'] 
credentials = 
ServiceAccountCredentials.from_json_keyfile_name('GoogleSpreadsheetCreds.json', scope) 
gc = gspread.authorize(credentials) 
sh = gc.open("MyWorksheet") 
worksheet = sh.sheet1 


@bot.event 
async def on_ready(): 
     print('Logged in as') 
     print(bot.user.name) 
     print(bot.user.id) 
     print('-----') 
     await bot.change_presence(game=discord.Game(name='Stackoverflow')) 



@bot.command(pass_context=True) 
@commands.has_role("Premium") 
async def sub(ctx, member: discord.Member = None): 
    global cell_name 
    if member is None: 
     member = ctx.message.author 

    #Delete user_command. 
    await bot.delete_message(ctx.message) 

    #Retrieve user from commander. 
    Username = '{0}'.format(member) 

    try: 
     #Try to find the username in spreadsheet. 
     cell_name = worksheet.find(Username) 
    except: #If we dont find the username. 
     await bot.say("Your name ("+Username+") was not found, please contact someone for help.") 

    if cell_name.value == Username: #If we find the username. 
     #Retrieve some values. 
     val = worksheet.cell(cell_name.row, cell_name.col+4) 
     val_date = worksheet.cell(cell_name.row, cell_name.col+3) 
     remaining_days = val.value 
     remaining_date = val_date.value 

     #Send a message to a member. 
     await bot.send_message(member, 
          "```Username: "+ Username+ 
          "\nRemaining days: "+remaining_days+ 
          "\nDate for expiration: "+remaining_date+"```") 

回答

1

您的訪問令牌在一段時間後過期。從OAuth 2.0 docs

  1. 刷新訪問令牌,如有必要。

訪問令牌的生命週期有限。如果您的應用程序需要在單個訪問令牌的生命週期之外訪問Google API,則可以獲取刷新令牌。刷新令牌允許您的應用程序獲取新的訪問令牌。

注意:將刷新令牌保存在安全的長期存儲中,只要它們保持有效,就繼續使用它們。限制適用於每個客戶端 - 用戶組合以及每個用戶在所有客戶端上發佈的刷新令牌的數量,這些限制是不同的。如果您的應用程序請求足夠的刷新令牌來超過其中一個限制,舊的刷新令牌將停止工作。

我不認爲gspread配備了處理刷新標記。您可能只需要抓住此異常並根據需要重新進行驗證。

編輯:

gspread源後,我想你可能能夠通過簡單地調用刷新令牌gc.login()

編輯:

issuegspread一對夫婦申請幾年前,但它沒有明顯的原因關閉。這裏是one approach來解決它:

def add_row(row): 
    try: 
     gs_client = gspread.authorize(creds) 
     gs_worksheet = gs_client.open("foo").sheet1 
     if creds.access_token_expired: 
      gs_client.login() # refreshes the token 
     gs_worksheet.append_row(row) 
    except Exception, e: 
     traceback.print_exc() 

但我認爲這是矯枉過正。你應該能夠你try:塊之前只是調用gc.login()權:

gc.login() 
try: 
    #Try to find the username in spreadsheet. 
    cell_name = worksheet.find(Username) 
except: #If we dont find the username. 
+0

謝謝,我會嘗試!所以gc.login()不需要輸入? – Simvid

+0

沒錯,沒有參數。您需要在訪問令牌過期後調用它。 – Jeff

+0

謝謝,這工作! – Simvid

0

這裏唯一合理的罪魁禍首是您的帳戶憑據。嘗試在Google Developer Console上創建新的憑據並使用它。

+0

嘗試,這也!謝謝 – Simvid