本文介绍了Python-Gspread请求错误401的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我目前正在制作一个Discord机器人,该机器人可以连接到Google电子表格(gspread)。 但是在运行了一段时间之后,它开始发出错误,并且它无法连接到我的gspread(除非我重新启动它)。 我收到的错误:( https://hastebin.com/odutucawuv.tex ) 忽略命令子中的异常回溯(最近一次调用是最近一次):文件 C: \Python36\lib\site-packagescordiscord.py-0.16.10- py3.6.egg\discord\ext\commands\core.py,第50行,在包装的 ret =来自coro(* args,** kwargs)的收益文件 C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py,第65行,在子 val = worksheet.cell(cell_name.row,cell_name.col + 4)文件 C:\Python36\lib\site-packages\gspread-0.6.2- py3.6.egg\gspread\models.py,第392行,位于单元格 self._cell_addr(row,col))文件 C:\Python36\lib 站点软件包 gspread-0.6.2- py3.6.egg gspread\client.py,第210行,位于get_cells_cell_id_feed $ b中$ br = self.session.get(url)文件 C:\Python36\lib\site-packages\gspread-0.6.2- py3.6.egg\gspread sessionhttpsession.py,第73行,在get 中返回self.request('GET',url,params = params,** kwargs)文件 C:\Python36\lib\ \site-packagesreadgspread-0.6.2- py3.6.egg\gspread\httpsession.py,第69行,在请求中 response.status_code,response.content)) gspread.exceptions.RequestError:(401,'401:b\'< HTML> \\n< HEAD> n< TITLE>未授权< / TITLE> \\ \n< / HEAD> \\n< BODY BGCOLOR =#FFFFFF TEXT =#000000> \\n< H1>未授权< / H1> \\n< H2>错误 401< / H2> \\n< / BODY> \\n< / HTML> \\n\'') 以上异常是以下异常的直接原因: 追溯(最近一次调用为最新):文件 C:\Python36\lib\site-packages\discord.py -0.16.10- py3.6.egg\discord\ext\commands\bot.py,行846,在comm的process_commands 中and.invoke(ctx)文件 C:\Python36\lib\site-packages\discord.py-0.16.10- py3.6.egg\discord\ext \commands\core.py,行374,从注入的($ ctx.args,** ctx.kwargs)调用收益文件 C:\Python36\lib\ site-packages\discord.py-0.16.10- py3.6.egg\discord\ext\commands\core.py,第54行,包裹在中,引发CommandInvokeError( e)来自e discord.ext.commands.errors.CommandInvokeError:命令引发了异常: RequestError:(401,'401:b\'< HTML> \\ n< HEAD> n< TITLE>未经授权的< / TITLE>< / HEAD> n< BODY BGCOLOR =#FFFFFF TEXT =#000000> ; \\n H1未经授权的/ H1gtnH2错误 401< H2\\n< / BODY> \\n< / HTML> \\n\'')忽略命令添加中的异常追溯(最近一次调用):文件 C:\Users\simvid-5\Desktop \Pogomoves\DiscordBot.py,行130,添加 cell_name = worksheet.find(str(member))文件 C:\Pyt hon36\lib\site-packages\gspread-0.6.2- py3.6.egg\gspread\models.py,第711行,在find 中返回self._finder( finditem,查询)文件 C:\Python36\lib\site-packages\gspread-0.6.2- py3.6.egg\gspread\models.py,第696行,在_finder cells = self._fetch_cells() File C:\Python36\lib\site-packages\gspread-0.6.2- py3.6 .egg\gspread\models.py,_ fetch_cells中的第331行 feed = self.client.get_cells_feed(self)文件 C:\Python36\lib\site-packages gspread-0.6.2- py3.6.egg\gspread\client.py,第176行,位于get_cells_feed r = self.session.get(url)文件中 C:\Python36\libpackagesite-packages\gspread-0.6.2- py3.6.egg\gspread\httpsession.py,第73行,得到 return self.request('GET',url,params = params,** kwargs)文件 C:\Python36\lib\site-packages\gspread-0.6.2- py3.6.egg\gspread\httpsession.py,第69行,在请求 response.status_code,response.content中)) gspread.exceptions.RequestError: (401,'401:b\'< HTML> \\n< HEAD> n< TITLE>未授权< / TITLE> n< / HEAD> \n< BODY BGCOLOR =#FFFFFF TEXT =#000000> \\n< H1>未授权< / H1> n< H2>错误 401< / H2> \\n< / BODY> \\n< / HTML> \\n\'') 在处理上述异常期间,发生了另一个异常: 追溯(最近一次通话):文件 C:\Python36\lib\site-packages\discord.py-0.16.10- py3 .6.egg\discord\ext\commands\core.py,第50行,包裹在中ret =来自coro(* args,** kwargs)文件的收益 C: \用户\simvid-5\桌面\Pogomoves\DiscordBot.py,第136行,添加 cell_list = worksheet.range('A2:A100')文件 C: Python36库站点包 gspread-0.6.2- py3.6.egg\gspread\models.py,第72行,在包装器中,返回方法(自我,* args,** kwargs)文件 C:\Python36\lib\site-packages\gspread-0.6.2- py3.6.egg\gspread\ models.py,第412行, ge params = {'range':name,'return-empty':'true'} 文件 C:\Python36\lib\site-packages\gspread-0.6.2 - py3.6.egg\gspread\client.py,第176行,位于get_cells_feed r = self.session.get(url)文件 C:\Python36\ libsite-packagesgspread-0.6.2- py3.6.egggspread\httpsession.py,第73行,在get 中返回self.request('GET ',url,params = params,** kwargs)文件 C:\Python36\lib\site-packages\gspread-0.6.2- py3.6.egg\ gspread\httpsession.py,第69行,在请求 response.status_code,response.content中)) gspread.exceptions.RequestError:(401, 401:b\< ; HTML> \\n< HEAD> n< TITLE>未授权< / TITLE> \\n< / HEAD> n< BODY BGCOLOR =#FFFFFF TEXT =#000000> \\n< H1>未授权< / H1> n< H2>错误 401< / H2> n< / BODY> \n< / HTML> \\n\'') 上面的异常是以下异常的直接原因: 追溯(大多数r最后一次通话):文件 C:\Python36\lib\site-packages\discord.py-0.16.10- py3.6.egg\discord\ext\ commands\bot.py,行846,在command_invoke(ctx)的process_commands 中,文件 C:\Python36\lib\site-packages\discord.py -0.16.10- py3.6.egg\discord\ext\commands\core.py,第374行,从注入的($ ctx.args,**调用收益ctx.kwargs)文件 C:\Python36\lib\site-packages\discord.py-0.16.10- py3.6.egg\discord\ext\命令\core.py,第54行,包裹在中,从 discord.ext.commands.errors.CommandInvokeError中引发CommandInvokeError(e):Command引发了异常: RequestError:( 401,'401:b\'< HTML> \\n< HEAD> n< TITLE>未授权< / TITLE> \\n< / HEAD> n<身体 BGCOLOR =#FFFFFF TEXT =#000000> n n< H1>未经授权< / H1> n n< H2>错误 401< / H2> \\n< / BODY> \\n< / HTML> \\n\'') 其中之一如果对理解上面的问题有帮助,可以使用我正在使用的功能,如果需要修复它,我可以提供更多代码: 导入不和谐导入异步随机导入泡菜导入os 导入gspread 导入时间 $ b来自oauth2client.service_account的$ b导入ServiceAccountCredentials来自discord.ext的导入命令 prefix ='!' def returnPrefix():全局前缀返回前缀 机器人=命令。Bot(returnPrefix()) 范围= ['https://spreadsheets.google.com/feeds'] 凭证= ServiceAccountCredentials.from_json_keyfile_name('GoogleSpreadsheetCreds.json',范围) gc = gspread.authorize(凭证) sh = gc.open( MyWorksheet)工作表= sh.sheet1 @ bot.event 异步定义on_ready(): print('Logged as') print( bot.user.name)打印(bot.user.id)p rint('-----')等待bot.change_presence(game = discord.Game(name ='Stackoverflow')) @bot .command(pass_context = True) @ commands.has_role( Premium)异步def sub(ctx,成员:discord.Member = None):全局cell_name 如果成员为None:成员= ctx.message.author #删除user_command。 等待bot.delete_message(ctx.message) #从司令员那里检索用户。 用户名=‘{0}’。format(成员) 尝试:#尝试在电子表格中查找用户名。 cell_name = worksheet.find(Username)除外:#如果找不到用户名。 await bot.say(未找到您的姓名( +用户名+),请与他人联系以寻求帮助。) 如果cell_name.value ==用户名:#如果找到用户名。 #检索一些值。 val = worksheet.cell(cell_name.row,cell_name.col + 4) val_date = worksheet.cell(cell_name.row,cell_name.col + 3)剩余_days = val.value 剩余日期= val_date.value #发送消息给成员。 等待bot.send_message(成员,``ʻUsername: +用户名+ \n剩余天数: + remaining_days + \n到期日: + missing_date +```) 解决方案您的访问令牌已过期一段时间后。从 OAuth 2.0文档: 如有必要,刷新访问令牌。 注意:将刷新令牌保存在安全的长期存储中,并在它们仍然有效的情况下继续使用它们。限制适用于每个客户端-用户组合以及所有客户端上的每个用户发出的刷新令牌的数量,这些限制是不同的。如果您的应用程序请求足够的刷新令牌以超过限制之一,则较旧的刷新令牌将停止工作。 我不相信 gspread 具有处理刷新令牌的功能。您也许可以捕获此异常并根据需要重新进行身份验证。 编辑: gspread 来源我认为您也许只需调用 gc.login() 编辑: 此问题是几年前向 gspread 提交的,但没有明显原因被关闭。这是一种解决方法: def add_row(row): try: gs_client = gspread.authorize(creds) gs_worksheet = gs_client.open ( foo)。sheet1 如果creds.access_token_expired: gs_client.login()#刷新令牌 gs_worksheet.append_row(row)例外,e: traceback.print_exc() 但我认为这太过分了。您应该可以在 try:块: $之前直接调用 gc.login() b $ b gc.login()尝试:#尝试在电子表格中查找用户名。 cell_name = worksheet.find(Username)除外:#如果找不到用户名。 I'm currently making a Discord-bot that connects to a Google-spreadsheet (gspread).But after I've been running it for a while it starts to hand out errors and it can't connect to my gspread anymore (unless i restart it).The error that I'm receiving: (https://hastebin.com/odutucawuv.tex)Ignoring exception in command subTraceback (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 wrappedret = yield from coro(*args, **kwargs)File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 65, in subval = 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 cellself._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_feedr = self.session.get(url)File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\httpsession.py", line 73, in getreturn 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 requestresponse.status_code, response.content))gspread.exceptions.RequestError: (401, '401:b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODYBGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error401</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_commandsyield 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 invokeyield 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 wrappedraise CommandInvokeError(e) from ediscord.ext.commands.errors.CommandInvokeError: Command raised an exception:RequestError: (401, '401:b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODYBGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error401</H2>\\n</BODY>\\n</HTML>\\n\'')Ignoring exception in command addTraceback (most recent call last):File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 130, in addcell_name = worksheet.find(str(member))File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\models.py", line 711, in findreturn self._finder(finditem, query)File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\models.py", line 696, in _findercells = self._fetch_cells()File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\models.py", line 331, in _fetch_cellsfeed = 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_feedr = self.session.get(url)File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\httpsession.py", line 73, in getreturn 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 requestresponse.status_code, response.content))gspread.exceptions.RequestError: (401, '401:b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODYBGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error401</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 wrappedret = yield from coro(*args, **kwargs)File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 136, in addcell_list = worksheet.range('A2:A100')File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\models.py", line 72, in wrapperreturn method(self, *args, **kwargs)File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\models.py", line 412, in rangeparams={'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_feedr = self.session.get(url)File "C:\Python36\lib\site-packages\gspread-0.6.2-py3.6.egg\gspread\httpsession.py", line 73, in getreturn 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 requestresponse.status_code, response.content))gspread.exceptions.RequestError: (401, '401:b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODYBGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error401</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_commandsyield 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 invokeyield 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 wrappedraise CommandInvokeError(e) from ediscord.ext.commands.errors.CommandInvokeError: Command raised an exception:RequestError: (401, '401:b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODYBGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error401</H2>\\n</BODY>\\n</HTML>\\n\'')And one of the functions that I'm using if it's to any help to understand the problem above, I can provide more of my code if it's necessary to fix it:import discordimport asyncioimport randomimport pickleimport osimport gspreadimport timefrom oauth2client.service_account import ServiceAccountCredentialsfrom discord.ext import commandsprefix = '!'def returnPrefix(): global prefix return prefixbot = 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 = [email protected] 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+"```") 解决方案 Your access token expires after some period of time. From the OAuth 2.0 docs: Refresh the access token, if necessary. Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens. Note: Save refresh tokens in secure long-term storage and continue to use them as long as they remain valid. Limits apply to the number of refresh tokens that are issued per client-user combination, and per user across all clients, and these limits are different. If your application requests enough refresh tokens to go over one of the limits, older refresh tokens stop working.I don't believe that gspread is equipped to deal with refresh tokens. You may just be able to catch this exception and reauthenticate as needed.EDIT:After looking at the gspread source I think you may be able to refresh your token by simply calling gc.login()EDIT:This issue was filed with gspread a couple of years ago but it was closed for no apparent reason. Here is one approach to solving it: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()but I think that's overkill. You should be able to just call gc.login() right before your try: block:gc.login()try: #Try to find the username in spreadsheet. cell_name = worksheet.find(Username)except: #If we dont find the username. 这篇关于Python-Gspread请求错误401的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 07-08 06:07