Jeg blev spurgt om jeg kunne hjælpe med et script til at logge ind på dinero.dk med Python. Det voldte noget besvær, så jeg endte med at kopiere min browsers handlinger ned til næsten mindste detalje. Det viste sig, at nogle cookies i et svar fra Dinero ikke blev fortolket rigtigt af Python-biblioteket Requests (hvorfor ved jeg ikke endnu, måske en fejl i Requests), så jeg blev nødt til at skrive en funktion til at gemme de rigtige cookies fra svaret.
Koden er her:
import requests
from bs4 import BeautifulSoup
session = requests.Session()
username = 'USERNAME HERE'
password = 'PASSWORD HERE'
# Very naive requests cookie header parser to account
# for apparant bug in requests cookie parsing
# NEVER use for anything else
def parse_cookie_header_names_and_values(set_cookie_header):
cookie_dict = {}
cookies = set_cookie_header.split(' httponly, ')
for cookie in cookies:
cook = cookie.split('; ')
name_value = cook[0]
coo = name_value.split('=')
# Only cookies with this string in them is needed for Dinero login
if '.Cookies.' in coo[0]:
cookie_dict[coo[0]] = coo[1]
return cookie_dict
# Visit login page and prepare to submit username
login_page_url = 'https://app.dinero.dk/'
visit_login_page = session.get(login_page_url)
login_soup = BeautifulSoup(visit_login_page.text, 'lxml')
username_form = login_soup.find('form', {'class': 'form-connect-login'})
username_form_data = {}
for input in username_form.find_all('input'):
try:
username_form_data[input['name']] = input['value']
except:
pass
username_form_data['Username'] = username
# Submit username and prepare to submit password
connect_url = 'https://connect.visma.com/'
submit_username = session.post(connect_url, data=username_form_data)
username_submitted_soup = BeautifulSoup(submit_username.text, 'lxml')
password_form = username_submitted_soup.find('form', {'class': 'form-connect-login'})
password_form_data = {}
for input in password_form.find_all('input'):
try:
password_form_data[input['name']] = input['value']
except:
pass
password_form_data['password'] = password
# Submit password and prepare to follow form redirect
password_url = 'https://connect.visma.com/password'
submit_password = session.post(password_url, data=password_form_data)
password_submitted_soup = BeautifulSoup(submit_password.text, 'lxml')
redirect_form = password_submitted_soup.find('form')
redirect_form_data = {}
for input in redirect_form.find_all('input'):
try:
redirect_form_data[input['name']] = input['value']
except:
pass
redirect_form_data['scope'] = redirect_form_data['scope'].replace(" ","+")
redirect_url = redirect_form['action']
# Follow form redirect
# Allow_redirects is set to False to account for a possible bug in requests cookie parsing
# where cookies are not stored to cookie jar. Response cookies are processed using custom
# function instead and the session cookie jar is overridden
follow_redirect = session.post(redirect_url, allow_redirects=False, data=redirect_form_data)
redirect_header_cookies = follow_redirect.headers['Set-Cookie']
logged_in_user_cookies = parse_cookie_header_names_and_values(redirect_header_cookies)
# Get front page of Dinero as logged in user
# Use these cookies for subsequent requests
visit_dinero = requests.get(login_page_url, cookies=logged_in_user_cookies)