Предыстория / Проблема
У меня есть веб-приложение, которое выполняет различные задания. Одно из этих заданий включает в себя запуск сценария python, который регистрируется в linkedin.
Когда я запускаю сценарий, запускается экземпляр безголового хрома, который переходит на страницу входа в систему и отправляет надлежащие учетные данные. До этого момента все работало нормально, но иногда linkedin отправляет мой запрос на URL контрольной точки и предлагает мне отправить специальный пин-код, отправленный на мою электронную почту, прежде чем я смогу продолжить.
Мне трудно понять, как реализовать эту условную логику c, на мой взгляд; в принципе, я хочу, чтобы я мог ввести пин-код в своем веб-приложении.
Ожидаемый результат
Запустить сценарий из django, чтобы войти в linkedin, и попросите пользователя ввести пин-код, если контрольная точка достигнута, в противном случае продолжайте, если контрольная точка не достигнута и вход был успешным.
То, что я пробовал
Google - Не удалось найти ничего, что указывало бы c на мою проблему.
Код ниже - На рисунке ниже показана моя текущая попытка. Я знаю, что это можно сделать, но я не уверен, стоит ли мне пытаться создать его в одном представлении или я должен попытаться передать свой экземпляр хрома в другое представление (объекты не сериализуются, поэтому я не уверен как бы я это сделал, может быть, я мог бы передать идентификатор хрома другому экземпляру моего веб-драйвера, но я не думаю, что это лучший метод?)
Ajax? - Я на самом деле не пробовал это, но я знаю, что это вариант.
Примечания **
Приведенный ниже код - это все. Но единственная важная часть, которую следует учитывать, - это представление. Я подумал, что добавление остальных может прояснить логику c и помочь кому-нибудь помочь мне. Надеюсь, это не слишком многословно!
Просмотр
def verify_linkedin(request):
"""Used for verifying login to linkedin with email pincode"""
ln = LinkedinScraper()
if ln.login_to_linkedin(username=os.getenv("LINKEDIN_USERNAME"), password=os.getenv("LINKEDIN_PASSWORD")):
return HttpResponse("<h1>You are verified</h1>")
else:
if request.method == "POST":
form = VerifyLinkedinForm(request.POST)
if form.is_valid():
print(form.cleaned_data)
pin_code = form['verification_key']
ln.authenticate_linkedin_login(pin_code)
return redirect("home")
else:
form = VerifyLinkedinForm()
context = {"form": form}
return render(request, "linkedin_verify.html", context)
Форма
class VerifyLinkedinForm(forms.Form):
verification_key = forms.CharField()
helper = FormHelper()
helper.form_method = "post"
helper.layout = Layout(
'verification_key',
FormActions(
Submit("submit", "Verify Linkedin", style="display: block; margin: auto; margin-bottom:2em;",
css_class="btn btn-success", ),
)
)
Шаблон
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
{% crispy form %}
{% endblock %}
Веб-браузер Backend
class LinkedinScraper(WebScraper):
"""Class for logging into linkedin with chromedriver and scraping linkedin"""
def __init__(self, headless=True, **kwargs):
super(LinkedinScraper, self).__init__()
self.setup_driver(headless=headless)
self.data = {}
self.pause = 10
self.retries = 0
self.max_retries = 3
def login_to_linkedin(self, username: str, password: str) -> bool:
""" Navigates to Linkedin login page and logs in with credentials"""
login_url = "https://www.linkedin.com/login"
self.driver.get(login_url)
user_element = self.driver.find_element("id", "username")
pass_element = self.driver.find_element("id", "password")
login_btn = self.driver.find_element_by_class_name(
"login__form_action_container"
)
self.login_and_authenticate(login_btn, user_element, pass_element, username, password)
if 'checkpoint' in self.driver.current_url:
return False
else:
return True
def authenticate_linkedin_login(self, pin_code: str):
""" Sometimes when logging into linkedin from a new ip address, linkedin will flag account for suscipicous access
If this happens we need to use a pin code sent to email and input it into the form.
This should be immedidately called after login_and_authenticate returns False
"""
if 'checkpoint' in self.driver.current_url:
verification_element = self.driver.find_element_by_xpath("//input[@id='input__email_verification_pin']")
print(pin_code)
self.random_send_keys(element=verification_element, keys=pin_code)
submit_element = self.driver.find_element("id", "email-pin-submit-button")
submit_element.click()
return True
else:
raise BaseException(f"Driver not on correct url, current url is {self.driver.current_url} -- Should contain checkpoint")