Python 3脚本无法使用OAuth API打开和关闭浏览器窗口进行登录

2024-04-20 04:03:20 发布

您现在位置:Python中文网/ 问答频道 /正文

导言

正如您将在下面看到的,我已经尝试了3种方法,主要是从stackoverflow上找到的。但我已经走到了死胡同

我正在尝试构建一个Python 3脚本,该脚本将向Spotify API发出请求。但首先,我需要通过OAuth进行身份验证,尤其是使用“授权代码”流,以获得“无止境”访问。见here。基本上,该过程包括以下主要步骤:

  1. GET请求https://accounts.spotify.com/authorize端点,包括以下几个参数:
    • 我注册的应用程序的client_id(可在我的Spotify Dev Dashbord上找到)
    • 这个redirect_uri
  2. (如果尚未登录,则为用户登录)
  3. (用户对我的应用程序的授权(如果尚未授权)
  4. 重定向到redirect_urihttps://example.com/callback?code=XYZ
  5. 获取XYZ授权代码,并将其传递回主脚本以进行下一步
  6. [POST请求https://accounts.spotify.com/api/token端点以获取access_token]->;我们不会在这篇文章中讨论这一点,下面的步骤也不会

由于需要用户的凭据,最重要的是需要用户的授权,我必须打开一个浏览器窗口。问题是,我无法从我的Python3脚本中以我希望的方式管理该窗口

尝试#1

首先,我从here给出的例子中得到了很大的启发,尤其是JavaScript中的this one

介绍步骤1。是用webbrowser.open_new_tab(url)来处理的。一旦我的应用程序被授权,Chrome(我的默认浏览器)就会被重定向到localhost。实际上,我的Python3脚本运行一个“一次性”服务器,它等待请求。收到后,它从window.path获取授权代码,然后用window.close()返回一些HTML代码到浏览器。这最后一段代码在应用程序已经授权时有效,但在Spotify登录页面或授权页面之间出现时无效。这种情况下窗户关不上。我开始明白,只有通过window.open()打开的窗口才能通过window.close()以编程方式关闭。在这一点上,我尝试了许多其他的变化,比如window.open('','_self').close();。如果应用尚未授权且用户尚未登录,则All无法关闭窗口

问题1:为什么不起作用?为什么它在已经登录+授权的情况下还能工作

问题2:我认为登录窗口会以某种方式改变窗口。。。但我怎样才能证实这一点呢?Chrome控制台不会有帮助,我甚至没有得到window.close的错误

问题3:是否有办法保留打开窗口的句柄并将其传递回回调javascript

尝试#2

结合seleniumchromedriver我可以成功地打开和关闭该窗口:

  1. browserdriver.execute_script("window.open('%s', '_self');" % url)
  2. window.close()

但问题是,selenium似乎更适合用于单元测试。因此,我无法让它在另一个打开的Chrome会话/实例中使用Chrome默认配置文件打开Chrome窗口。只有在创建临时用户数据文件夹时,它才能正常工作,但这样做时,登录凭据无法从默认配置文件中检索(或保存),这对我不合适

问题4:我看到了一种解决方法,将整个用户数据文件夹复制到某个位置,并使用它打开Chrome,这样它就可以对默认配置文件进行写访问。这不适合我。。。你看到另一个解决方案了吗

尝试#3

回到使用webbrowser。主脚本现在打开一个浏览器,该浏览器不会直接发出GET引入步骤1的请求。(前面在第2步第1步中提到)。它向localhost发出请求,该请求使用window.open(url, '_self')向浏览器发送一些HTML代码。但是后来,在回调javascript中,'window.close()'将不再工作。即使用户已登录且应用已授权!(在这个特殊案例中,它在尝试1中起了作用)

问题5:为什么?在本例中window.open()甚至是显式的,而它不是在尝试#1中,因为它隐藏在webbrowser类中

如果我使用window.open(url),我可以稍后使用window.close()关闭新窗口。但是第一个窗口仍然打开,这里又出现了一个新问题:新窗口是一个被阻止的弹出窗口,因为它是通过脚本打开的,因此无法跟踪到用户操作(与引言中使用“登录”按钮的示例不同)

问题6:如何打开单个浏览器窗口,而不是阻止的弹出窗口,并在检索授权代码时将其关闭

还有什么想法吗?

注意:我对浏览器重定向到的URI的简单副本不感兴趣,然后粘贴到Python解释器中以检索Spotify帐户服务提供的授权代码(例如Spotipy)


Tags: 代码用户https脚本com应用程序urlclose