如何在没有POST的情况下使用python请求传输表单数据?

时间:2019-06-12 10:48:10

标签: python html forms python-requests

我正在编写一小段python代码,以登录我的几个“投资”网站,并得出当前已投资的金额。我正在使用pythons请求库并分析html源以识别表单和要填写的字段。 因此,表单可能看起来像这样:

 <form class="onboarding-form" id="loginForm" action="https://estateguru.co/portal/login/authenticate" method="post" data-redirect="https://estateguru.co/portal/home">
              <div class="row">
                <div class="col-md-6">
                  <div class="form-group">
                     <input type="text" class="form-control main-input" name="username">
                     <label class="bmd-label-floating main-label">E-Mail</label>
                     <em id="username-error" class="error bmd-help help-block" style="display:none;">This field is required.</em>
                    </div>
                 </div>
              <div class="col-md-6">
                    <div class="form-group">
                       <input type="password" class="form-control main-input login-pass" name="password">
                        <label class="bmd-label-floating main-label long-label">Passwort (Mindestens 8 Zeichen)</label>
                        <em id="password-error" class="error bmd-help help-block" style="display:none;">This field is required.</em>
                         <a href="#" class="show-pass-icon"><i class="zmdi zmdi-eye"></i></a>
                   </div>
                  </div>
                </div>

在这种情况下,我的代码如下:

import requests
_username = 'xxx'
_password = 'yyy'

loginUrl = 'https://estateguru.co/portal/login/authenticate'
readUrl = 'https://estateguru.co/portal/portfolio/overview'
with requests.session() as s:

    payload = {"username": _username, "password": _password}

    final = s.post(loginUrl, data = payload)
    result = s.get(readUrl)
    print(result)

这对许多网站都具有吸引力!但是现在我有了一个表单中没有“ method = post”的网站,所以我不知道如何传递表单数据。 html部分(来自http://www.reinvest24.com/en/login)如下所示:

<form>
    <div class="form-group">
        <input type="text" id="email" placeholder="Email" value="" name="email" maxLength="100" class="form-control"/>
    </div>
    <div class="form-group">
        <input type="password" id="password" placeholder="Password" value="" name="password" maxLength="100" class="form-control"/>
    </div>
    <p class="forgot text-right">
        <a href="/en/forgot-password"><span>Forgot password?</span></a>
    </p>
    <input type="submit" class="btn btn-success" value="Login"/>
        <p class="reg text-center">
            <span>Don&#x27;t have an account?</span>
             <a href="/en/registration">
            <span>Sign up</span></a>
        </p>
</form>

因此,在没有弄清楚方法的情况下,我尝试了

final = s.get(loginUrl, data = payload)

但没有成功。在这两种情况下,结果都是一个html输出,上面写着“正在加载授权详细信息...”。

所以我的问题是:我错过了正确的方法(POST / GET)来传输数据还是我错过了一些其他参数?有些网站需要会话令牌,我可以从登录站点本身撤消该令牌(例如https://www.mintos.com/de/login中的情况),但是我认为这不是问题所在。

1 个答案:

答案 0 :(得分:0)

默认情况下,当方法设置为GET时,将忽略HTTP请求的正文(表单数据)。因此,您不应该尝试通过GET提交请求(通过GET传输敏感信息不仅不安全,而且服务器只会忽略您的请求的用户名/密码)。

这里的问题是页面正在做一些JavaScript魔术,以通过另一个URL提交您的请求。每当您尝试登录该网站时,请打开您的Web检查器并观看“网络”标签。您应该看到请求已发布到https://api-frontend.reinvest24.com/graphql

当我们检查此POST请求时,我们可以看到数据是以JSON主体而不是表单主体的形式传输的。因此,您的请求应与此类似:

login_url = 'https://api-frontend.reinvest24.com/graphql'
payload = {
    "operationName": "login",
    "variables": {
        "email": EMAIL,
        "password": PASSWORD
    },
    "query": "mutation login($email: String!, $password: String!) {\n  login(email: $email, password: $password)\n}\n"
}
r = s.post(url=login_url, json=payload)

# note that we used the 'json' parameter here not 'data'

Chrome Web检查器是您的朋友,在这里观察登录时如何传输数据。

祝你好运!