'ahrefs.com authorization using python requests

I'm trying to login to https://ahrefs.com/user/login. Everything works fine in browser, but it shows the webpage "Under maintenance" using python. Can someone tell me what should I do to login there? My code:

from requests import Session


data = {'email': 'email', 'password': 'pwd'}

headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'ru,en-US;q=0.8,en;q=0.6,uk;q=0.4',
    'dnt': '1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'
    }

s = Session()
r = s.get('https://ahrefs.com', headers=headers)
r = s.post('https://ahrefs.com/user/login', data=data, headers=headers)

print(r.text)

This is the webpage I get using this code:

<!DOCTYPE html >
<html>
<head>
<meta charset="utf-8" />
<title>Updating the service - Ahrefs</title>

<meta name="description" content="We are currently updating our service and adding some cool new features!" >

<link rel="shortcut icon" href="/favicon.ico" />

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css">
<link href='https://fonts.googleapis.com/css?family=Lato:400,300,100italic,100,300italic,400italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'>
<link href="/assets/css/static.css?170317" media="screen" type="text/css" rel="stylesheet">

<link rel="apple-touch-icon" href="/images/apple-touch-icon.png" >
<link rel="apple-touch-icon" sizes="76x76" href="/images/apple-touch-icon-76.png" >
<link rel="apple-touch-icon" sizes="120x120" href="/images/touch-icon-iphone-retina.png" >


<script type="text/javascript">
    !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.1.0";
        analytics.load('Zg9CNakKRAv2PeY9l2SBX7XsvcyF4GoH');
        analytics.page('500');
    }}();
</script>

<script type="text/javascript">
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-28303106-1', 'ahrefs.com');
    ga('require', 'displayfeatures');

    // Load the plugin.
    ga('require', 'linker');

    // Define which domains to autoLink.
    ga('linker:autoLink', ['fastspring.com']);
    ga('send', 'pageview');

</script>

</head>

<body class="page-error">
    <header class="page__notfound">
        <nav class="navbar no-radius navbar-ahrefs-header">
            <a class="logo navbar-brand" href="/dashboard">Ahrefs</a>
        </nav>
    </header>



    <article class="page__notfound__center container text-xs-center static-wrapper">
        <div class="page__notfound__center--content">
            <div class="page__notfound__error--img text-xs-center">
                <img class="img-fluid" src="/images/service/robot-maintenance.png" alt="Updating service" />
            </div>
            <h1 class="page__notfound__title">Page under maintenance</h1>
            <p class="page__notfound__text">We are currently updating our service and adding some cool new features.
                <br>We will be back shortly. Thank you for your patience.
                <span class="clearfix"></span>
                <a href="javascript:window.location.href=window.location.href" class="page__notfound__link btn btn-secondary btn-ahrefs-sm"><span class="reload-icon"></span> Try again</a>
            </p>
        </div>
    </article>

    <script>
        window.intercomSettings = {
            app_id: "dic5omcp"
        };
        (function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/dic5omcp';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()
    </script>
    <!-- end of intercom IO code -->
</body>
</html>


Solution 1:[1]

If you try a log in with the wrong credentials and see the results in under inspect > Network > Fetch/XHR you will see that the page you need to call corresponds to the _LOGIN_URL variable below.

You will also see that the body of the request looks like the body variable below.

# Build URL of page for login
_AUTH_BASE_URL = 'https://auth.ahrefs.com'
_LOGIN_URL = _AUTH_BASE_URL + '/auth/login'
# Body for log in
body = json.dumps(
    {
        'remember_me': True,
        'auth': {
            'password': "login_pass",
            'login': "login_mail"
        }
    }
)
# Create session
session = requests.Session()
session.auth = ("login_mail", "login_pass")
# Log in and attach the cookies from the response to session
login_response = session.request(method='POST', url=_LOGIN_URL,
                               data=body)
session.cookies = login_response.cookies

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MattSt