Python 3 скрипт не может открыть И закрыть окно браузера для входа в систему с OAuth API - PullRequest
0 голосов
/ 03 апреля 2020

ВВЕДЕНИЕ

Как вы увидите ниже, я уже попробовал 3 метода, в основном из того, что я мог найти здесь на stackoverflow. Но я зашел в тупик.

Я пытаюсь создать сценарий Python 3, который будет отправлять запросы в API Spotify. Но сначала мне нужно пройти аутентификацию через OAuth и, в частности, используя поток «Код авторизации», чтобы получить «бесконечный» доступ. Смотрите здесь . В основном процесс состоит из следующих основных шагов:

  1. GET запрос конечной точки https://accounts.spotify.com/authorize с несколькими параметрами, включая:
    • client_id моего зарегистрированного приложения (находится на моем Spotify Dev Dashbord)
    • the redirect_uri
  2. (логин пользователя, если он еще не авторизован)
  3. (авторизация пользователя для моего приложения, если еще нет авторизовано)
  4. перенаправлено на redirect_uri: https://example.com/callback?code=XYZ
  5. , получите код авторизации XYZ и передайте его обратно в основной скрипт для следующего шага
  6. [POST запрос к https://accounts.spotify.com/api/token конечной точке, чтобы получить access_token] -> мы не будем освещать эту точку в этом посте, ни следующие шаги.

Из-за необходимости учетных данных пользователя и больше всего для авторизации пользователя мне нужно открыть окно браузера. Дело в том, что я не могу управлять этим окном так, как мне хотелось бы из моего Python 3 скрипта.

ПОПЫТКА # 1

Прежде всего, я был очень вдохновлен примерами, приведенными здесь и, в частности, этим в JavaScript.

ВВЕДЕНИЕ На шаге 1 рассматривается webbrowser.open_new_tab(url). После авторизации моего приложения Chrome (мой браузер по умолчанию) перенаправляется на localhost. Действительно, мой сценарий Python 3 запускает "одноразовый" сервер SimpleHTTPRequestHandler, который ожидает запрос. При получении он получает код авторизации от window.path, а затем отправляет обратно некоторый код HTML в браузер с window.close(). Этот последний бит кода работает, когда приложение уже авторизовано, но не когда между ними появляется страница входа в систему Spotify или страница авторизации. Окно не закроется в этом случае. Я понял, что только окно, открытое через window.open(), может быть программно закрыто через window.close(). В этот момент я пробовал много других вариантов, например window.open('','_self').close();. Все не смогли закрыть окно, если приложение еще не авторизовано, а пользователь еще не вошел в систему.

ВОПРОС 1 : Почему оно не будет работать? И почему он вообще работает, когда уже залогинен + авторизован?

ВОПРОС 2 : Я думаю, что окно входа в систему как-то меняет окно ... Но как я могу это проверить? Chrome консоль не поможет, я даже не получаю сообщение об ошибке window.close.

ВОПРОС 3 : есть ли способ сохранить дескриптор открытого окна и передать его обратному вызову javascript?

ПОПЫТКА # 2

Объединение selenium и chromedriver Я мог бы успешно открыть и закрыть это окно:

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

Но дело в том, что селен, похоже, больше предназначен для модульного тестирования. Поэтому я не смог заставить его открыть окно Chrome, используя профиль по умолчанию Chrome, когда он уже используется в другом открытом Chrome сеансе / экземпляре. Он работает правильно только тогда, когда я создаю временную папку с пользовательскими данными, но при этом учетные данные для входа не могут быть получены из профиля по умолчанию (и не сохранены), что мне не подходит.

ВОПРОС 4 : я видел обходной путь, который заключается в том, чтобы скопировать всю папку пользовательских данных куда-нибудь и использовать ее для открытия Chrome, чтобы у нее был доступ на запись в профиль по умолчанию. Меня это не устраивает ... Видите ли вы другое решение?

ATTEMPT # 3

Вернуться к использованию webbrowser. Основной сценарий теперь открывает браузер, который напрямую не выполняет запрос GET ВВЕДЕНИЯ на шаге 1. (ранее упоминалось url в ПОПЫТКЕ № 2, шаг 1.). Он делает запрос к localhost, который доставляет некоторый код HTML в браузер с window.open(url, '_self'). Но позже, в обратном вызове javascript, 'окно. close () `больше не будет работать. Даже если пользователь уже вошел в систему и приложение авторизовано! (в данном конкретном случае это работало в ПОПЫТКЕ № 1)

ВОПРОС 5 : Почему это так? window.open() даже явный в этом случае, тогда как он не был в ATTEMPT # 1, потому что скрыт в классе webbrowser.

Если я использую window.open(url), я могу закрыть новое окно с помощью window.close() позже. Но первое окно остается открытым, и здесь снова возникает новая проблема: новое окно является заблокированным всплывающим окном, потому что оно открывается скриптом и поэтому не может быть отслежено до действия пользователя (в отличие от примера, приведенного во ВВЕДЕНИИ, в котором используется «Логин» "кнопка).

ВОПРОС 6 : Как я могу открыть одно окно браузера, а не заблокированное всплывающее окно, и закрыть его, управляя при этом получением кода авторизации?

Есть еще идеи?

Примечание. Меня не интересует решение с простой копией URI, на который перенаправлен браузер, а затем вставьте Python интерпретатор для получения кода авторизации, предоставляемого сервисом Spotify Accounts (как, например, Spotipy).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...